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 IX:IUnknown{/**/};
Interface IY:IUnknown{/**/};
Class CA:public 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的基址加上偏移址。