为什么我在 2 个不同的实例中得到相同的 __vfptr ?
我对通过 IDispatch/IUnknown 指针看到的 __vfptr 感到困惑。 我正在创建进程内自由线程 COM 对象 (IMyContainer)。在这个对象内部,我需要保留指向实现相同 IMyInterface 的 com 对象的 2 个不同实例的指针。所以我调用 CreateAndSaveDispToMap() 两次。
我的想法是将它们的 IDispatch 指针保留在某些 std::map 中。此时我怀疑每个实例的 refCount 都会为 1。事实也是如此。但令人惊讶的是,我发现我通过 pUnk 为 2 个不同的调度指针获得了相同的 __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);
}
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);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
每个多态对象都会有一个 __vfptr,它是指向对象实际类的 vtable 的指针。每个不同的类都会生成一个 vtable。这就是为什么对于同一类的任何两个对象,它们的 __vfptr 都将具有相同的值。
要区分不同的 COM 对象,请检索并比较它们的
IUnknown
接口指针。这就是所谓的对象标识。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__vfptr
s will have identical values.To distinguish between different COM objects retrieve and compare their
IUnknown
interface pointers. That's called object identity.谢谢,我发现 IUnknown 上的函数地址是相同的,而且一定是这样。
但仍然不理解AddRef/Release的行为。当我在 ExposePointer() 中进入调试模式时,我看到第二个后续调用不会将 refCount 带到 3。它会将其带回到 2。
但是如果我调用 ForgetExposePointer() 两次,它会将其带回 3。
为什么返回通过 Variant* 结果调度指针或忘记返回这样的值会给我不同的结果?我的理解是,在 Call 1 和 Call 2 之间发生了一些对 Release() 的隐藏调用......
Thanks, I figured out that function's addresses on IUnknown are the same and must be so.
But still don't undersatand the behaviour of AddRef/Release. When I step in debug mode in ExposePointer() I see that the second consequitive call will not bring refCount to 3. It will bring it back to 2.
But if I call ForgetExposePointer() twice instead it will bring it to 3.
Why returning dispatch pointer through Variant* Result or forgetting to return such value gives me different result? My undersanding that between Call 1 and Call 2 some hidden call to Release() occur...