代码如下,我要从一个接口获得另外一个接口的指针:
//下面的代码展示从IIMContactManager接口指针成功地获得了IIMGroup接口指针
CComPtr<IIMContactManager> spCM;
//...这里省略一行代码表示从一个COM对象里获得IIMContactMananger接口
CComQIPtr<IIMGroup> pGroup(spCM);
//而以下的代码却失败了
CComPtr<IIMGroup> pGroup;
hr = spCM->QueryInterface(__uuidof(IIMGroup), reinterpret_cast<void**>(&pGroup));
hr返回的是E_NOITNTERFACE,也就是说QueryInterface函数的实现里提示没有这个接口,而这个QueryInterface是ATL实现的,它提示没有这个接口指针的话,说明你没有将这个IIMGroup接口插入到接口的驱动表里,查找了一下代码,果然,在BEGIN_COM_MAP里没有COM_INTERFACE_ENTRY(IIMGroup),但是有COM_INTERFACE_ENTRY(IIMContactManager),这个IIMContactManager接口是从 IIMGroup接口继承下来的,那个COM对象从IIMContactManager继承下来,也就是间接地从IIMGroup继承下来,因此CComQIPtr在构造函数里,直接将
spCM的指针赋值给了pGroup指针,然后AddRef,的确是会成功的。但是由于没有在QueryInterface所建立的接口表中明确地指明可以查询到这个接口,因此QueryInterface失败了!
这个bug很隐晦,也许CComQIPtr设计地有些问题!按照COM规范,如果你通过一个接口可以获得另外一个接口,则必须在你的QueryInterface里指针可以查询到这个接口。而我遇到的这个问题里,我根本没有指明可以查询到这个接口,CComQIPtr利用C++语言的多态性就直接将接口指针赋值给了另外基类的接口指针,然后AddRef,我认为是违反了COM规范的。
//下面的代码展示从IIMContactManager接口指针成功地获得了IIMGroup接口指针
CComPtr<IIMContactManager> spCM;
//...这里省略一行代码表示从一个COM对象里获得IIMContactMananger接口
CComQIPtr<IIMGroup> pGroup(spCM);
//而以下的代码却失败了
CComPtr<IIMGroup> pGroup;
hr = spCM->QueryInterface(__uuidof(IIMGroup), reinterpret_cast<void**>(&pGroup));
hr返回的是E_NOITNTERFACE,也就是说QueryInterface函数的实现里提示没有这个接口,而这个QueryInterface是ATL实现的,它提示没有这个接口指针的话,说明你没有将这个IIMGroup接口插入到接口的驱动表里,查找了一下代码,果然,在BEGIN_COM_MAP里没有COM_INTERFACE_ENTRY(IIMGroup),但是有COM_INTERFACE_ENTRY(IIMContactManager),这个IIMContactManager接口是从 IIMGroup接口继承下来的,那个COM对象从IIMContactManager继承下来,也就是间接地从IIMGroup继承下来,因此CComQIPtr在构造函数里,直接将
spCM的指针赋值给了pGroup指针,然后AddRef,的确是会成功的。但是由于没有在QueryInterface所建立的接口表中明确地指明可以查询到这个接口,因此QueryInterface失败了!
这个bug很隐晦,也许CComQIPtr设计地有些问题!按照COM规范,如果你通过一个接口可以获得另外一个接口,则必须在你的QueryInterface里指针可以查询到这个接口。而我遇到的这个问题里,我根本没有指明可以查询到这个接口,CComQIPtr利用C++语言的多态性就直接将接口指针赋值给了另外基类的接口指针,然后AddRef,我认为是违反了COM规范的。