最近在看COM聚合技术时遇到一个关于QueryInterface的问题。在《COM技术内幕》和《COM原理与应用》中都是寥寥数句带过,看起来很易理解,我却看了许久才有所领悟。
先说明一下,为了节省篇幅,对于一些约定俗成的代码和变量,下文不再进行说明,如内部组件指向外部组件的m_pUnknownOuter和外部组件指向内部组件的m_pUnknownInner等,这些内容在相关书籍都有描述。
问题描述:
在外部组件CB聚合内部组件CA时,内部组件的非委托未知接口示意如下:
struct INondelegatingUnknown
{
virtual HRESULT __stdcall NondelegatingQueryInterface(const IID&, void**) = 0;
virtual ULONG __stdcall NondelegatingAddRef() = 0;
virtual ULONG __stdcall NondelegatingRelease() = 0;
};
这里,查询函数为NondelegatingQueryInterface。
NondelegatingQueryInterface的实现示意代码如下:
HRESULT __stdcall CA::NondelegatingQueryInterface(const IID& iid, void** ppv)
{
if (iid == IID_IUnknown)
{
*ppv = static_cast<INondelegatingUnknown*>(this);
}
else if (iid == IID_IY)
{
*ppv = static_cast<IY*>(this);
}
.....
}
同时,CA还要实现内部组件的委托未知接口:
ULONG __stdcall CA::QueryInterface(const IID& iid, void** ppv)
{
return m_pUnknownOuter->QueryInterface(iid, ppv);
}
现在假设外部组件CB实现了接口IX, 内部组件CA实现了组件IY,那么根据上述两本书中的描述,在CB查询IY接口时使用如下代码:
m_pUnknownInner->QueryInterface(IID_IY, ppv);