COM 学习笔记

 

QueryInterface函数

主要用于COM接口的查询。它是COM接口定义IUnknown的成员函数,客户可以调用QueryInterface来决定组件是否支持某个特定的接口。

       组件COM接口都是从IUnkonwn接口继承而来,任何一个接口都可以用IUnknown的成员QueryInterface来获取它所支持的其它接口。

1)定义:

       HRESULT _stdcall QueryInterface(const IID& iid,void ** ppv);

第一个参数十所需接口的标识,是一个接口标识符IID结构。 第二个参数存放所请求接口指针的地址。

      2)使用过程:

       假定已有一个指向IUnknown的指针pI,为知道相应的组件是否支持某个特定的接口,调用QueryInterface,传给它一个接口标识符。若成功返回,那就是可以使用它返回的指针。

Void foo(IUnknown * pI)

{

       IX *pIX=NULL;

HRESULT hr=pI->QueryInterface(IID_IX,(void **)&pIX);

If(SUCCEEDED(hr))

pIX->Fx();

}

该函数用于查询pI是否支持由IID_IX所标识的接口。

IUnknown的继承不是虚拟基类。COM接口不能按照虚拟方式继承它。

3)实现:

Interface IXIUnknown{/**/}

Interface IYIUnknown{/**/}

Class CApublic IX,public IY{/**/};

主要通过判断标识符是否为CA的支持类型,来判断是否为存在在CA中的COM

HRESULT _stdcall CA:;QueryInterface(const IID &iid,void **ppv)

{

       If(iid==IID_IUnknown)

{

       *ppv=static_cast<IX *>(this);

}

Else if(iid==IID_IX)

{

       *ppv=static_cast<IX*>(this);

}

Else if (iid==IID_IY)

{

       *ppv=static_cast<IY*>(this);

}

Else

{

       *ppv=NULL;

Return E_NOINTERFACE;

}

Static_cast<IUnknown*>(*ppv)->AddRef();

Return S_OK;

}

4)关于其中的类型转换

   程序中若将this指针直接转换成IUnknown*是不明确的。因为存在两个基类接口,需要指明是转换向哪一个接口的IUnknown

Static_cast<IUnknown*> (static_cast<IX *>(this))

在类型转换时,CA按照顺序存放它的基类接口及其实现,其this指针可以用IX代替(地址值相同)。

IY则需要CA的基址加上偏移址。