COM 學(xué)習(xí)筆記

 

QueryInterface函數(shù)

主要用于COM接口的查詢。它是COM接口定義IUnknown的成員函數(shù),客戶可以調(diào)用QueryInterface來決定組件是否支持某個特定的接口。

       組件COM接口都是從IUnkonwn接口繼承而來,任何一個接口都可以用IUnknown的成員QueryInterface來獲取它所支持的其它接口。

1)定義:

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

第一個參數(shù)十所需接口的標(biāo)識,是一個接口標(biāo)識符IID結(jié)構(gòu)。 第二個參數(shù)存放所請求接口指針的地址。

      2)使用過程:

       假定已有一個指向IUnknown的指針pI,為知道相應(yīng)的組件是否支持某個特定的接口,調(diào)用QueryInterface,傳給它一個接口標(biāo)識符。若成功返回,那就是可以使用它返回的指針。

Void foo(IUnknown * pI)

{

       IX *pIX=NULL;

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

If(SUCCEEDED(hr))

pIX->Fx();

}

該函數(shù)用于查詢pI是否支持由IID_IX所標(biāo)識的接口。

IUnknown的繼承不是虛擬基類。COM接口不能按照虛擬方式繼承它。

3)實現(xiàn):

Interface IXIUnknown{/**/};

Interface IYIUnknown{/**/}

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

主要通過判斷標(biāo)識符是否為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)關(guān)于其中的類型轉(zhuǎn)換

   程序中若將this指針直接轉(zhuǎn)換成IUnknown*是不明確的。因為存在兩個基類接口,需要指明是轉(zhuǎn)換向哪一個接口的IUnknown。

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

在類型轉(zhuǎn)換時,CA按照順序存放它的基類接口及其實現(xiàn),其this指針可以用IX代替(地址值相同)。

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