i have a Ibase interface which has a method DoBase().
i derive two classes from this base interface class CBase called
CDrived_1:CBase
CDrived_2 CBase
both class overrides Dobase Method.
CDrived_1:obase
{
__super:obase()
}
CDrived_2:obase
{
__super:obase()
}
i have a COM method which returns the Ibase Interface.
HRESULT GetInterface ( id, IBASE** pp)
{
if ( id == 0)
{
hr = CDrived_1::CreateInstance(pp);
}
if (id == 0)
{
hr = CDrived_2::CreateInstance(pp);
}
}
now in the client application if i call
IBase* pp = NUL
GetInterface (id , &pp);
pp->Dobase() //which function should be called??
i was expecting that either CDrived_1:obase() or CDrived_2:obase() should be called. since function is virtual.
but it is calling CBase:obase()/// Why?
how should i do it so that derived one gets called.
now i have come up with a demo project and i am a little bit confused.
1. I created a ATL project ATLTest (EXE).
2. i added a interface IService
3. i added one method Get(IBase **ppBase ) in the Iservice Interface
4. i added Ibase ATL simple Object and added a function Test() { MessageBox(NULL. L"Base::Test",L"Base::Test",0) }
5. now added a C++ class Derived1 and added Test() function of exact same signature.
CComObject<Derived1>* g_pDerived = NULL;
STDMETHODIMP CService::Get(IBase** ppbase)
{
//case1 : Calls the derived one
CComObject<Derived1> *d;
CComObject<Derived1>::CreateInstance(&d);
*ppbase = d;
return S_OK;
//Case2/:singleton : calls the derived one
if ( g_pDerived == NULL )
{
CComObject<Derived1>::CreateInstance( &g_pDerived );
*ppbase = g_pDerived;
}
//case:3 Derived1::CreateInstance (ppbase ) // this one i am using and it calls the BASE one Why??
return S_OK;
}
which approach is correct. i could get the derived class function by case 2 but is it correct.
derived1.h
Code:
#include "Base.h"
class Derived1 :public CBase
{
public:
Derived1(void);
~Derived1(void);
STDMETHOD ( Test )(void);
};
now could any body explain me how should i correct my design
regards
deepak
Last edited by Deepak_Sharma; December 1st, 2009 at 11:36 AM.
Reason: formating
Your description looks incomplete. Why don't you upload your test solution here?
And one more point. Strictly saying, you must not use case 3. As long as you return COM interface (IBase), it should have IUnknown implemented. But the latter is implemented in CComObject<> whyle Derived1 is just a template parameter for it, and must not be instantiated any other way.
here is the attached sample for it. it would be very nice if you could explain. i am stuck here
Case 3: Ibase has Iunknown implemented.
one more confusion i have is that when i return the interface pointer do it need to addref or client needs to. i think i need to call addref(). client would just release it. so that it would be unloaded automatically.
however i do not see any addRef() when i use Case 3. i e.
Derived1::CreateInstance (ppbase ) // does it mean that it would call addref automatically
because in all other cases (case 1 and case 2 )i saw random crashes if i do not explicitly call AddRef()
however i do not see any addRef() when i use Case 3.
Something makes me think that in case 3 there is no IUnknown implemented. Otherwise you would see AddRef alright. This exactly is what I was talking about.
Last edited by Igor Vartanov; December 3rd, 2009 at 06:16 PM.
//case1 : Calls the derived one
CComObject<Derived1> *d;
CComObject<Derived1>::CreateInstance(&d);
*ppbase = d;
This makes compiler to call this:
Code:
template <class Base>
HRESULT WINAPI CComObject<Base>::CreateInstance(CComObject<Base>** pp) throw()
{
ATLASSERT(pp != NULL);
if (pp == NULL)
return E_POINTER;
*pp = NULL;
HRESULT hRes = E_OUTOFMEMORY;
CComObject<Base>* p = NULL;
ATLTRY(p = new CComObject<Base>())
if (p != NULL)
{
p->SetVoid(NULL);
p->InternalFinalConstructAddRef();
hRes = p->_AtlInitialConstruct();
if (SUCCEEDED(hRes))
hRes = p->FinalConstruct();
if (SUCCEEDED(hRes))
hRes = p->_AtlFinalConstruct();
p->InternalFinalConstructRelease();
if (hRes != S_OK)
{
delete p;
p = NULL;
}
}
*pp = p;
return hRes;
}
All seems perfect. Your Derived1 class is correctly passed for instance creation, that's why you have correct Test method. And automatic AddRef as well.
Now about more tricky thing.
Code:
//case:3 Derived1::CreateInstance (ppbase ) // this one i am using and it calls the BASE one Why??
* The Best Reasons to Target Windows 8
Learn some of the best reasons why you should seriously consider bringing your Android mobile development expertise to bear on the Windows 8 platform.