亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

C++ COM編程之QueryInterface函數(一)

2020-05-23 14:21:01
字體:
來源:轉載
供稿:網友
這篇文章主要介紹了C++ COM編程之QueryInterface函數(一),QueryInterface是組件本身提供對自己查詢的一個接口,需要的朋友可以參考下
 
 

前言

組件對外公布的是接口;一個組件可以實現多個接口,也就是說可以對外公布多個接口,之前也總結過了,你很少會100%的去完全了解一個組件的所有接口,就像你去學習編程一樣,你幾乎不可能去成為編程中的全才。那么,既然我們不能去完全的了解一個組件提供的所有接口,那么我們在實際開發中,如何去判斷一個組件是否提供對應的接口呢?看文檔?是的,是個好主意,在文檔的海洋,找到一個知識點,真的很難,浪費時間和精力;其實,組件本身就提供對自己查詢的一個接口,讓客戶去詢問組件,問它是否支持某個接口,在經過多次的這種詢問之后,客戶對于組件的認識將越來越清晰;而我這篇文章和下一篇文章就是對這種詢問機制進行詳細的剖析和總結。

關于IUnknown

上面說到組件本身提供一個對自己查詢的接口,那么這個接口是什么呢?這就是大名鼎鼎的IUnknown接口了,IUnknown接口在Windows SDK的unknwn.h中定義,它的定義如下:

 

復制代碼代碼如下:

interface IUnknown
{
public:
    virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, _COM_Outptr_  void **ppvObject) = 0;
    virtual ULONG STDMETHODCALLTYPE AddRef( void) = 0;
    virtual ULONG STDMETHODCALLTYPE Release( void) = 0;
};

 

這里的STDMETHODCALLTYPE表示調用方式,也就是windows API的__stdcall方式??梢钥吹剑贗Unknown中定義了一個名為QueryInterface的函數??蛻艨梢哉{用QueryInterface來判斷組件是否支持某個特定的接口,而對于剩下的AddRef和Release兩個接口操作,我會在之后的文章中進行總結。

所有的COM接口都需要繼承IUnknown接口;因此,如果某個客戶擁有一個IUnknown接口的指針,它并不需要知道它所擁有的接口指針到底是指向什么類型的,而只需要知道此接口可以用來查詢其它接口就行了。

由于所有的COM接口都首先繼承了IUnknown,再根據對之前的文章COM編程——接口的背后 的理解,我們可以知道每個接口的vtbl中的前三個函數都是QueryInterface,AddRef和Release。這就使得所有的COM接口都可以被當成IUnknown接口來處理。如果某個接口的vtbl中的前三個函數不是這三個,那么它將不是一個COM接口。由于所有的接口都是從IUnknown繼承而來的,因此所有的接口都支持QueryInterface。所以,組件的任何一個接口都可以被客戶用來獲取它所支持的其他接口。由于所有的接口指針同時也將是IUnknown指針,客戶并不需要單獨維護一個代表組件的指針,它所關心的將僅僅是接口的指針。

既然,我們可以只用QueryInterface去詢問組件是否支持某個接口,但是,這一切都是基于獲得了IUnknown接口指針之后,才能進行的操作,那么如何獲得一個指向組件的IUnknown接口指針呢?我們可以實現一個CreateInstance函數,它建立一個組件并返回一個IUnknown指針;對于客戶來說,可以調用CreateInstance獲得IUnknown指針,而不用使用new操作符了。在系統的總結了COM的所有基礎知識之后,我再說說系統提供的一個創建組件實例的API函數。

關于QueryInterface

IUnknown中包含一個名為QueryInterface的成員函數,客戶可以通過此函數來查詢某個組件是否支持某個特定的接口。若支持,QueryInterface將返回一個指向此接口的指針;否則返回值將是一個錯誤代碼;然后客戶可以接著查詢其它接口。

從QueryInterface函數的聲明中可以看出,QueryInterface有兩個參數,第一個參數標識客戶所需的接口,這個參數是一個接口標識符(IID)結構,在之后的文章中,我會總結有關IID的知識的;第二個參數用來存放所請求的接口的地址。QueryInterface返回的是一個HRESULT值,它是一個具有特定結構的32位值,之后我也會進行總結的;對于返回的HRESULT值,在實際開發中,需要使用SUCCEEDED宏或FAILED宏去進行判斷HRESULT值是表示成功還是失敗。

QueryInterface的簡單實現

總結了QueryInterface的簡單實現,說白了,就是簡單工廠模式的實現;上面也說了,就是根據客戶提供的IID接口標識符,然后獲得對應的接口的指針,返回對應的接口的指針;如果組件支持客戶指定的接口,那么應返回S_OK以及相應的指針;若不支持,返回值應是E_NOINTERFACE,并將相應的指針返回值置成NULL。下面通過一個簡單的例子來說明QueryInterface的簡單實現:

C++ COM編程之QueryInterface函數(一)

比如有上述的一個結構;接口IX和IY都繼承自IUnknown接口,組件CA實現了IX和IY接口,那么QueryInterface的實現應該像下面這樣:

 

復制代碼代碼如下:

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;
}

 

QueryInterface的簡單使用

當我獲得了一個IUnknown指針以后,就可以調用對應的QueryInterface進行查詢了,如下:

復制代碼代碼如下:

void Fod(IUnknown *pI)
{
     IX *pIX = NULL;
     // Ask for interface IX
     HRESULT hr = pI->QueryInterface(IID_IX, (void **)&pIX);
     // Check the return value
     if (SUCCEEDED(hr))
     {
          // Use the interface
          pIX->Fx();
     }    
}

 

完整的例子

上面說了那么多了,現在提供一個完整的例子,將上面的各種理論知識都在實際代碼中進行了實踐,讓各位能更好的理解QueryInterface。(下載)。

總結

QueryInterface理解起來比較簡單,但是,它的理論知識還是必須要去掌握的,理論是一切的基礎,沒有理論作為支撐,任何實際的操作都不會那么可靠和可信,所以,這篇文章總結的偏于理論多一些。由于QueryInterface部分的內容比較多,使用一篇文章無法總結的齊全,所以,之后我還會繼續總結關于QueryInterface的第二部分。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲国产成人精品久久久国产成人一区| 日韩精品免费观看| 日韩av电影手机在线观看| 奇米成人av国产一区二区三区| 国产一区二区三区中文| 精品无码久久久久久国产| 九九热视频这里只有精品| 亚洲男人天堂久| 91九色精品视频| 黑人狂躁日本妞一区二区三区| 精品中文字幕在线观看| 久久亚洲国产精品成人av秋霞| 日韩在线观看免费av| 亚洲免费成人av电影| 成人黄色生活片| 一区二区三区 在线观看视| 91在线视频导航| 欧美性xxxxxxx| 亚洲欧美中文日韩在线v日本| 国产精品第七十二页| 麻豆国产va免费精品高清在线| 91国内产香蕉| 欧美日韩激情网| 成人福利网站在线观看| 中文字幕国产亚洲| 国产免费一区视频观看免费| 欧美激情第99页| 欧美精品成人91久久久久久久| 日韩成人av一区| 影音先锋欧美在线资源| 亚洲黄一区二区| 国产精品久久久久久久久男| 欧美资源在线观看| 日韩国产高清污视频在线观看| 日韩毛片在线看| 欧美性xxxx在线播放| 欧美日韩一区二区三区在线免费观看| 亚洲国产精品va在线看黑人| 欧美精品福利视频| 成人久久久久久久| 日韩av在线最新| 91精品视频在线看| 国产丝袜高跟一区| www.日韩欧美| 伊人一区二区三区久久精品| 欧美精品免费播放| 国产精品一区=区| 亚洲人成在线观看网站高清| 久久99国产精品自在自在app| 精品av在线播放| 精品久久久一区二区| 国产拍精品一二三| 在线看欧美日韩| 免费不卡在线观看av| 91wwwcom在线观看| 成人美女免费网站视频| 欧洲成人免费aa| 国产成人中文字幕| 国产精品久久久久久久久久久久久| 91国产一区在线| 国产精品久久久久久一区二区| 午夜精品久久久久久久男人的天堂| 91亚洲精品一区二区| 亚洲精品456在线播放狼人| 亚洲影院色无极综合| 久热精品视频在线免费观看| 国产在线一区二区三区| 91亚洲va在线va天堂va国| 国产美女直播视频一区| 亚洲视频综合网| 欧美日韩精品中文字幕| 国产精品啪视频| 欧美性少妇18aaaa视频| 久久免费观看视频| 欧美日韩精品二区| 国产精品7m视频| 欧美精品激情在线| 国产www精品| 在线观看精品自拍私拍| 91在线观看免费观看| 国产午夜精品麻豆| 欧美成年人网站| 成人黄色短视频在线观看| 欧美日韩国产在线播放| 欧美激情免费看| 亚州成人av在线| 超碰91人人草人人干| 国产丝袜精品视频| 91在线中文字幕| 成人有码在线视频| 97国产精品人人爽人人做| 欧美日韩免费网站| 欧美日韩在线免费观看| 久久亚洲欧美日韩精品专区| 欧美一区二区三区免费视| 亚洲aaaaaa| 日韩免费av片在线观看| 色偷偷噜噜噜亚洲男人| 国产成人午夜视频网址| 亚洲人成网7777777国产| 国产精品露脸自拍| 97超级碰碰人国产在线观看| 久久国产加勒比精品无码| 成人h视频在线观看播放| 亚洲高清久久久久久| 国产精品久久久久久久久久久久久| 欧美在线国产精品| 欧美电影免费在线观看| 午夜精品久久久99热福利| 亚洲欧美色婷婷| 日韩在线免费高清视频| 国产97人人超碰caoprom| 亚洲欧美中文字幕在线一区| 亚洲91精品在线| 精品国产31久久久久久| 日韩动漫免费观看电视剧高清| 国产精品国产三级国产aⅴ9色| 国产欧美在线看| 国产啪精品视频网站| 美女视频久久黄| 91亚洲永久免费精品| 亚洲www在线| 久久精品视频亚洲| 午夜精品久久久久久99热软件| 欧美极品少妇xxxxx| 一区二区欧美亚洲| 日本最新高清不卡中文字幕| 日韩av电影院| 国产精品欧美激情在线播放| 久久人人爽人人爽人人片av高清| 国产婷婷成人久久av免费高清| 欧美精品免费在线| 日韩欧美在线字幕| 欧美日韩中文字幕日韩欧美| 国产精品福利网| 久久久久久国产三级电影| 国产不卡视频在线| 国产精品久久久久久一区二区| 欧美精品一区二区三区国产精品| 精品中文字幕在线2019| 亚洲天堂av网| 性金发美女69hd大尺寸| 国产啪精品视频网站| 国产精品久久网| 国产精品在线看| 亚洲va久久久噜噜噜| 亚洲肉体裸体xxxx137| 成人免费看黄网站| 国产成人亚洲精品| 国产精品久久久久久久久久新婚| zzijzzij亚洲日本成熟少妇| 亚洲欧美成人精品| 精品久久久香蕉免费精品视频| 成人网页在线免费观看| 精品欧美aⅴ在线网站| 久久精品色欧美aⅴ一区二区| 亚洲人精品午夜在线观看| 亚洲精品视频播放| 日日狠狠久久偷偷四色综合免费| 国产一区二区在线免费| 欧美大片va欧美在线播放| 欧美高清视频在线| 国产69精品久久久| 亚洲欧美综合精品久久成人|