假设我有一个COM接口指针
IMyInterface *pInterface = 0x12696340;
我可以通过跟随函数调用从调试器看到这必须由CMyImplementer实现,但该类位于0x12686e50。
我的问题是,COM如何将接口与实现类相关联?必须有一些方法可以从接口转换为类指针 - 如何做到这一点?
答案 0 :(得分:1)
在我熟悉的一个实现中,会发生什么。不确定这种布局有多普遍,但它可以让你知道什么是可能的。
在32位模式下,内存中类的布局如下所示:
[ (4 bytes) ptr to vtable for IUnknown ]
[ (4 bytes) ptr to vtable for IDispatch ]
[ (4 bytes) ptr to vtable for IMyInterface ] <--- pInterface points to here
[ (....) member variables of the class implementing CoYourClass etc. ]
内存中的其他位置(此类的所有对象的一个实例):
[ (12 bytes) vtable for CoYourClass::IUnknown ]
[ (28 bytes) vtable for CoYourClass::IDispatch ]
[ (4*n bytes) vtable for CoYourClass::IMyInterface ] <---- (*pInterface) points here
vtable中的条目指向thunk。当您调用pInterface->Foo();
时,将检索与Foo
对应的vtable条目,这是thunk的代码地址。该thunk接收pInterface
作为其this
指针。 thunk知道它是CoYourClass类中的IMyInterface thunk并且它在这种情况下减去8
字节的固定偏移量以检索指向对象开头的指针。然后,thunk调用您编写的实际代码来实现Foo
,将调整后的指针传递给this
。
OP注意:通过在调用对象时检查调试器中的内存和变量,可以找出编译器使用的布局(如果调试器允许您从客户端代码转到进程内对象的服务器代码,则最简单) )
答案 1 :(得分:0)
COM通常不要求接口指针指向同一物理对象;这完全取决于每个特定COM对象的实现。但是,任何逻辑对象的IUnknown
指针必须相等,并用作对象标识。因此,当您需要检查身份时,您只需QueryInterface
IUnknown
并检查该指针。