Reputation: 2917
Say I have a COM Interface pointer
IMyInterface *pInterface = 0x12696340;
I can see from the debugger by following the function call that this must be implemented by CMyImplementer, but that class is at 0x12686e50.
My question is, how does COM relate the interface to the implementing class? There must be some way to convert from the interface to the class pointer - how would one do that?
Upvotes: 1
Views: 232
Reputation: 141554
Here's what happens, in one implementation I'm familiar with. Not sure how universal this layout is but it may give you an idea of what is possible.
The layout of the class in memory, in 32-bit mode, looks like this:
[ (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. ]
Elsewhere in memory (one instance of this for all objects of the class):
[ (12 bytes) vtable for CoYourClass::IUnknown ]
[ (28 bytes) vtable for CoYourClass::IDispatch ]
[ (4*n bytes) vtable for CoYourClass::IMyInterface ] <---- (*pInterface) points here
The entries in the vtable point to thunks. When you call pInterface->Foo();
, the vtable entry corresponding to Foo
is retrieved, which is the code address of a thunk. That thunk receives pInterface
as its this
pointer. The thunk knows that it is an IMyInterface thunk within a CoYourClass class and it subtracts the fixed offset of 8
bytes in this case to retrieve a pointer to the start of the object. Then the thunk calls the actual code you've written to implement Foo
, passing the adjusted pointer as this
.
Note to OP: You could figure out the layout your compiler uses by inspecting memory and variables in your debugger as you call an object (easiest if your debugger lets you step from the client code into the server code for in-process object)
Upvotes: 1
Reputation: 145239
COM does not require interface pointers in general to point to the same physical object; this is all up to the implementation of each particular COM object. However, the IUnknown
pointers for any logical object, must be equal, and serve as object identity. So you can just QueryInterface
for IUnknown
and check that pointer, when you need to check identity.
Upvotes: 0