描述:
#define BASE_OFFSET(ClassName,BaseName) \
(DWORD ( static_cast<BaseName*> (reinterpret_cast\
<ClassName*> (0x1000000))) - 0x1000000)
#define BEGIN_INTERFACE_TABLE(ClassName) \
typedef ClassName_ITCls; \
const INTERFACE_ENTRY *GetInterfaceTable(void) {\
static const INTERFACE_ENTRY table[]={\
#define IMPLEMENTS_INTERFACE(Itf) \
{&IID_##Itf, ENTRY_IS_OFFSET,BASE_OFFSET(_ITCls, Itf) },
#define IMPLEMENTS_INTERFACE_AS(req,Itf) \
{&IID_##req, ENTRY_IS_OFFSET, BASE_OFFSET(_ITCls, Itf) },
#define END_INTERFACE_TABLE() \
{0, 0, 0 } }; return table; }
其中INTERFACE_ENTRY的定义如下:
typedef struct _INTERFACE_ENTRY
{
const IId* pIID;
INTERFACE_FINDER pfnFinder;
DWORD dwData;
} INTERFACE_ENTRY;
上一个结构中的INTERFACE_FINDER 的定义为:
typedef HRESULT (*INTERFACE_FINDER) (void *pThis,DWORD dwData,REFIID riid,void **ppv);
#define ENTRY_IS_OFFSET INTERFACE_FINDER(-1) //这句话又是什么意思?
解决方案1:
定义INTERFACE_ENTRY表用于查找IID:
BASE_OFFSET宏:获取接口在实现类中的偏移;
BEGIN_INTERFACE_TABLE(ClassName)
IMPLEMENTS_INTERFACE(Itf)
END_INTERFACE_TABLE()
三个宏定义GetInterfaceTable函数,并填充INTERFACE_ENTRY表。
如此操作是实现类似于MFC的表格驱动模型。将QueryInterface函数的操作委托给内部表格查找函数
InnerFindInterface,再由InnerFindInterface调用GerInterfaceTable获得接口表,遍历表格中的pIID,根据表项中的
INTERFACE_FINDER指针判定是否有另外的查找函数或是直接取得接口指针(Itf *)(this + dwData(偏移量))。
混分
解决方案3: 好久没有回帖!我来说两句!
首先,1、typedef HRESULT (*INTERFACE_FINDER) (void *pThis,DWORD dwData,REFIID riid,void **ppv);
#define ENTRY_IS_OFFSET INTERFACE_FINDER(-1) //这句话又是什么意思?
意思是宏ENTRY_IS_OFFSET的值为INTERFACE_FINDER类型并且它的指针值是-1,也就是地址是0xfffffff
,具体的意思是为了表明接口映射表中某个接口是偏移的。
2、#define BASE_OFFSET(ClassName,BaseName) \
(DWORD ( static_cast<BaseName*> (reinterpret_cast\
<ClassName*> (0x1000000))) - 0x1000000)
这个宏是偏移量,它是先用reinterpret_cast<ClassName*>强制转换一个地址0x1000000为ClassName*的指针地址,接着再用static_cast<BaseName*> 转换成基类(其实是接口)指针减去原始地址计算出固定偏移量。不知道我说清楚了没有,如果你对static_cast和reinterpret_cast强制转换不太了解那么就去查一下!
3、BEGIN_INTERFACE_TABLE 意思就是初始化一个表,我想可能是老侯翻译的时候漏掉了一点代码我这里没法明确的解释,如果你想知道的更具体我建议你去看看atl的实现,哈哈!以为我喜欢atl!
4、#define IMPLEMENTS_INTERFACE(Itf) \
{&IID_##Itf, ENTRY_IS_OFFSET,BASE_OFFSET(_ITCls, Itf) }.....
意思就是添加一条记录到表中!格式就是{&IID_##Itf, ENTRY_IS_OFFSET,BASE_OFFSET(_ITCls, Itf) }
5、#define END_INTERFACE_TABLE() \
{0, 0, 0 } }; return table; }这个就不用解释了!一看就知道!hoho!
#define ENTRY_IS_OFFSET INTERFACE_FINDER(-1) //这句话又是什么意思?
因它COM的结口映射实现上就是维护的一张表,-1表示这张表到此结束。
#define ENTRY_IS_OFFSET INTERFACE_FINDER(-1)
就是说这个函数此处没有用它,把它置为-1 啦!
INTERFACE_FINDER(-1) 是把-1转换为INTERFACE_FINDER类型函数指针,以防类型不匹配报错!