Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I'm not going to ask why are you doing it this way, but perhaps this could help... Every COM object must implement at least the IUnknown interface. Hence, the first four bytes of the COM object instance is the pointer to IUnknown object. The first four bytes of the IUnknown object (and any other object with virtual functions) is the pointer to vtbl.</p> <p>(There is no error checking in this example, so please don't split hair on that subject.)</p> <p>I used an instance of IReferenceClock for demonstration.</p> <pre><code>int main() { CoInitialize( NULL ); IReferenceClock* pRefClock; HRESULT hr = CoCreateInstance( CLSID_SystemClock, NULL, CLSCTX_INPROC_SERVER, IID_IReferenceClock, (void**)&amp;pRefClock ); DWORD* pIUnknownAddress = (DWORD*)pRefClock; DWORD* pVTBLaddress = (DWORD*)*pIUnknownAddress; // for example, the next interface could be accessed like this DWORD* pNextInterfaceAddress = ( (DWORD*)pRefClock ) + 1; DWORD* pNextVTBLaddress = (DWORD*)*pNextInterfaceAddress; // and you would access virtual functions in the same way as QueryInterface, AddRef and Release below in this example HRESULT (__stdcall *pQueryInterfaceFunction)(void*, REFIID, void**); ULONG (__stdcall *pAddRef)( void* ); ULONG (__stdcall *pRelease)( void* ); // IUnknown looks like this: // // virtual HRESULT QueryInterface( REFIID riid, void** ppvObject); // virtual ULONG AddRef( void ); // virtual ULONG Release( void ); // // So, the first function in vtbl is QueryInterface, the second is AddRef... pQueryInterfaceFunction = (HRESULT (__stdcall*)(void*, REFIID, void**))*pVTBLaddress; pAddRef = (ULONG (__stdcall *)( void* ))*( pVTBLaddress + 1 ); pRelease = (ULONG (__stdcall *)( void* ))*( pVTBLaddress + 2 ); // Note: extra void* is actually this pointer.. see below that we pass pRefClock to every call IUnknown* pUnknown; UINT nRefCount; hr = pQueryInterfaceFunction( pRefClock, IID_IUnknown, (void**)&amp;pUnknown ); if( SUCCEEDED( hr ) ) { nRefCount = pUnknown-&gt;Release(); ATLTRACE( TEXT( "nRefCount = %d\n" ), nRefCount ); } nRefCount = pAddRef( pRefClock ); ATLTRACE( TEXT( "nRefCount after AddRef() call = %d\n" ), nRefCount ); nRefCount = pRelease( pRefClock ); ATLTRACE( TEXT( "nRefCount after Release() call = %d\n" ), nRefCount ); nRefCount = pRefClock-&gt;Release(); CoUninitialize(); return 0; } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload