Search code examples
c++windowscom

How do COM Interface pointers relate to the implementing class?


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?


Solution

  • 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)