Com 为什么我在两个不同的实例中得到相同的vfptr?

Com 为什么我在两个不同的实例中得到相同的vfptr?,com,idispatch,Com,Idispatch,我对通过IDispatch/IUnknown指针看到的u vfptr感到困惑。 我在无进程线程COM obj(IMyContainer)中创建。在这个对象中,我需要保留指向实现相同IMyInterface的com对象的两个不同实例的指针。所以我调用CreateAndSaveDispToMap()两次 我的想法是将它们的IDispatch指针保存在一些std::map中。此时,我怀疑每个实例的refCount都将为1。事实就是这样。但令人惊讶的是,我看到我通过朋克为两个不同的调度指针获得了相同的v

我对通过IDispatch/IUnknown指针看到的u vfptr感到困惑。 我在无进程线程COM obj(IMyContainer)中创建。在这个对象中,我需要保留指向实现相同IMyInterface的com对象的两个不同实例的指针。所以我调用CreateAndSaveDispToMap()两次

我的想法是将它们的IDispatch指针保存在一些std::map中。此时,我怀疑每个实例的refCount都将为1。事实就是这样。但令人惊讶的是,我看到我通过朋克为两个不同的调度指针获得了相同的vftbl

为什么??AddRef()和Release()如何工作正常

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);
}

每个多态对象都有一个
\uuu vfptr
,它是指向对象实际类的vtable的指针。每个不同的类生成一个vtable。这就是为什么对于同一类的任何两个对象,它们的
\uu vfptr
都具有相同的值


要区分不同的COM对象,请检索并比较它们的
IUnknown
接口指针。这就是所谓的。

谢谢,我发现IUnknown上函数的地址是相同的,必须是相同的

但是仍然不了解AddRef/Release的行为。当我在ExposePointer()中进入调试模式时,我看到第二个conrequisive调用不会将refCount设置为3。这将使它回到2

但是如果我调用forgeTexposeInter()两次,它会将其调到3

为什么通过Variant*Result返回分派指针,或者忘记返回这样的值会给我不同的结果?我的理解是,在调用1和调用2之间,出现了一些对Release()的隐藏调用


v表只是一个地址表。所有对象实例都有一个v形表,它不存储任何对象状态。
STDMETHODIMP CMyContainer::ExposePointer([in]int index, [out, retval] VARIANT* Result)
{
VariantInit(Result);
IDispatch* pDisp = m_map[index].second;
V_VT(Result) = VT_DISPATCH;
V_DISPATCH(Result) = pDisp;
refCount_x = pDisp->AddRef();    // Increment, because we expose
}

STDMETHODIMP CMyContainer::ForgetExposePointer([in]int index, [out, retval] VARIANT* Result)
{
VariantInit(Result);
IDispatch* pDisp = m_map[index].second;
refCount_y = pDisp->AddRef();
}


MyApp::Function1(...)
{
CreateAndSaveDispToMap(...);   // refCount is 1 now
VARIANT var1;
VARIANT var2;
pMyContainer->ExposePointer(index, &var1);  // Call 1
pMyContainer->ExposePointer(index, &var2);  // Call 2
}
MyApp::Function2(...)
{
CreateAndSaveDispToMap(...);   // refCount is 1 now
VARIANT var1;
VARIANT var2;
pMyContainer->ForgetExposePointer(index, &var1);
pMyContainer->ForgetExposePointer(index, &var2);
}