描述:
例子在 COM原理与应用 samples\ch4\aggre
在这里下载: http://book.yzcc.com/down.asp?id=1577&no=1
A是被B聚合 CompCtrl 是测试程序
HRESULT CB::Init()
{
IUnknown *pUnknownOuter = (IUnknown *)this;
HRESULT result = ::CoCreateInstance(CLSID_CompA,pUnknownOuter,CLSCTX_INPROC_SERVER,IID_IUnknown, (void **)&m_pUnknownInner) ;
if (FAILED(result))
return E_FAIL;
result = m_pUnknownInner->QueryInterface(IID_SomeInterface, (void **)&m_pSomeInterface);
......
}
在CB:Init()中,CoCreateInstance创造对象A,得到(INondelegatingUnknown *)类型的指针m_pUnknownInner (见CAFactory::CreateInstance) 。而INondelegatingUnknown 没有继承IUnknown,怎么会有QueryInterface ? m_pUnknownInner->QueryInterface 怎么会调用NondelegatingQueryInterface?
class INondelegatingUnknown
{
public:
virtual HRESULT __stdcall NondelegationQueryInterface(const IID& iid, void **ppv) = 0 ;
virtual ULONG __stdcall NondelegatingAddRef() = 0;
virtual ULONG __stdcall NondelegationRelease() = 0;
};
解决方案1:
画图应该比较清楚,这里大概说明一下:
INondelegatingUnknown -- NondelegationQueryInterface
-- NondelegatingAddRef
-- NondelegationRelease
IUnknown -- QueryInterface
-- AddRef
-- Release
INondelegatingUnknown和IUnknown只有三个纯虚函数,两个类每个函数的偏移量是一致的。
比如访问NondelegatingAddRef或AddRef都是偏移一函数(好像是4个字节,记得不清楚了).
m_pUnknownInner虽然是个INondelegatingUnknown类型,但转换成IUnknown后就有QueryInterface函数了,但实际调用是NondelegationQueryInterface函数。你可以在调试状态下看看程序是调用QueryInterface还是NondelegationQueryInterface。
虽然函数名不同,但INondelegatingUnknown与IUnknown的内存布局一样。 调用时,只认内存,不认名字。明白了? 如果没有,去看《深入探讨C++对象模型》