gpt4 book ai didi

com - 如何迭代 COM coclass 的 vtable?

转载 作者:行者123 更新时间:2023-12-04 13:41:11 27 4
gpt4 key购买 nike

如何迭代/访问 COM coclass 的 vtable,它将实现其公开接口(interface)的方法?

我需要访问存储其接口(interface)公开方法的所有地址的 vtable 部分。

例如Math 是 COM 对象,它暴露的接口(interface)是“Operations”,“Sum”是这个接口(interface)的方法,如何获取“Sum”的地址?

最佳答案

我不会问你为什么要这样做,但也许这会有所帮助......
每个 COM 对象必须至少实现 IUnknown 接口(interface)。因此,COM 对象实例的前四个字节是指向 IUnknown 对象的指针。 IUnknown 对象(以及任何其他具有虚函数的对象)的前四个字节是指向 vtbl 的指针。

(此示例中没有错误检查,因此请不要在该主题上 fork 。)

我使用 IReferenceClock 的一个实例进行演示。

int main()
{

CoInitialize( NULL );

IReferenceClock* pRefClock;
HRESULT hr = CoCreateInstance( CLSID_SystemClock, NULL, CLSCTX_INPROC_SERVER, IID_IReferenceClock, (void**)&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**)&pUnknown );

if( SUCCEEDED( hr ) )
{
nRefCount = pUnknown->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->Release();

CoUninitialize();

return 0;
}

关于com - 如何迭代 COM coclass 的 vtable?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2419674/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com