Search code examples
comidispatch

Why I am getting same __vfptr for 2 different instances?


I got confused with __vfptr which I see through IDispatch/IUnknown pointers. I'm creating in-proc free threaded COM obj (IMyContainer). Inside this object I need to keep pointers to 2 different instances of com objects which implements same IMyInterface. So I call CreateAndSaveDispToMap() twice.

My idea is to keep their IDispatch pointers in some std::map. At this moment I suspect that each instance will have refCount of 1. And it is so. But suprisingly I see that I am getting same __vftbl through pUnk for 2 different dispatch pointers.

Why? How it's possible that AddRef() and Release() works fine?

HRESULT CMyContainer::CreateAndSaveDispToMap(...)
{
...
IMyInterface* pMyInterface = NULL;
hr = ::CoCreateInstance(CLSID_MyInterface, NULL, CLSCTX_INPROC_SERVER, IID_IMyInterface, (void**)&pMyInterface);
pMyInterface->QueryInterface(IID_IDispatch, (void**)&pDisp);
pMyInterface->Release();    // Call Release since QI already called AddRef()
...

IUnknown* pUnk = NULL;
pDisp->QueryInterface(IID_IUnknown, (void**)&pUnk);
int refCount = pUnk->Release();
...
AddToMap(pDisp);
}

Solution

  • Each polymorphic object will have a __vfptr that is a pointer to the vtable of the actual class of the object. One vtable is generated per each distinct class. That's why for any two objects of the same class their __vfptrs will have identical values.

    To distinguish between different COM objects retrieve and compare their IUnknown interface pointers. That's called object identity.