《深入解析ATL》5.6.1小节“接口映射表链”中说到,派生类的接口映射表通过 COM_INTERFACE_ENTRY_CHAIN 来使用基类的接口映射表。同时强调,接口映射表的第一个项必须是一个简单项,所以在派生类的接口映射表中至少一个派生类的接口放在第一项,即说明 COM_INTERFACE_ENTRY_CHAIN 不能放在第一项。最后还说到,如果派生类没有其他接口,那么可把 IUnknown 放在第一项。例如:class CBetterBeachBall: public CBeachBall
{
public:
BEGIN_COM_MAP(CBetterBeachBall)
COM__INTERFACE_ENTRY(IUnknown)
COM__INTERFACE_ENTRY_CHAIN(CBeachBall)
END_COM_MAP()
} 问题是:如果 CBeachBall 实现了两个以上的接口,那么 COM__INTERFACE_ENTRY(IUnknown)会不会产生二义性?
{
public:
BEGIN_COM_MAP(CBetterBeachBall)
COM__INTERFACE_ENTRY(IUnknown)
COM__INTERFACE_ENTRY_CHAIN(CBeachBall)
END_COM_MAP()
} 问题是:如果 CBeachBall 实现了两个以上的接口,那么 COM__INTERFACE_ENTRY(IUnknown)会不会产生二义性?
解决方案 »
- 数据库奇怪问题
- 一个超级简单问题
- 各位高手帮帮忙,请问用MFC开发的ActiveX控件,嵌入网页,在本地可以显示,为什么在局域网其他机子不能显示?
- 请问,我的这段OpenGL程序为什么显示是黑屏?(代码:全)
- 关于Socket服务端的问题,请大家帮我分析下。谢谢~~
- 如何动态创建二维数组?
- 记录集为什么不能update
- 有关SQL问题
- 定义函数GetName(LPSTR buffer, long nBufferLength)时,什么情况下省略nBufferLength参数也能保证strlen(buffer)能正常工作?
- 谁能帮助我
- VC2010中编译Sqlite3为静态库并带加密功能的方法。
- 菜鸟求教:多维数组怎么改变里面的内容?
你意思是说书上例子写错了,应该是下面这样?!class CBetterBeachBall:
public CBeachBall,
public IUnknown{
public:
BEGIN_COM_MAP(CBetterBeachBall)
COM__INTERFACE_ENTRY(IUnknown)
COM__INTERFACE_ENTRY_CHAIN(CBeachBall)
END_COM_MAP()
}
<cpp>
ATLINLINE ATLAPI AtlInternalQueryInterface(
void* pThis,
const _ATL_INTMAP_ENTRY* pEntries,
REFIID iid,
void** ppvObject)
{
...
if (InlineIsEqualUnknown(iid)) { // use first interface
IUnknown* pUnk=(IUnknown*)((INT_PTR)pThis+pEntries->dw);
pUnk->AddRef();
*ppvObject = pUnk;
return S_OK;
}
while (pEntries->pFunc != NULL) {
...//对于不是IUnknown 的iid进行查表
}
return E_NOINTERFACE;
}
</cpp>
对于IUnknown,ATL只检查map的第一项,并且做类似static_cast找到vtbl定位,所以查找IUnknown不会出现branch
对于非IUnknown才会一个一个检索.