最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時(shí)間:2014年10月01日 10:55:39   作者:果凍想  
這篇文章主要介紹了C++ COM編程之QueryInterface函數(shù)(一),QueryInterface是組件本身提供對自己查詢的一個(gè)接口,需要的朋友可以參考下

前言

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

關(guān)于IUnknown

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

復(fù)制代碼 代碼如下:

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表示調(diào)用方式,也就是windows API的__stdcall方式??梢钥吹?,在IUnknown中定義了一個(gè)名為QueryInterface的函數(shù)??蛻艨梢哉{(diào)用QueryInterface來判斷組件是否支持某個(gè)特定的接口,而對于剩下的AddRef和Release兩個(gè)接口操作,我會(huì)在之后的文章中進(jìn)行總結(jié)。

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

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

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

關(guān)于QueryInterface

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

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

QueryInterface的簡單實(shí)現(xiàn)

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

比如有上述的一個(gè)結(jié)構(gòu);接口IX和IY都繼承自IUnknown接口,組件CA實(shí)現(xiàn)了IX和IY接口,那么QueryInterface的實(shí)現(xiàn)應(yīng)該像下面這樣:

復(fù)制代碼 代碼如下:

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的簡單使用

當(dāng)我獲得了一個(gè)IUnknown指針以后,就可以調(diào)用對應(yīng)的QueryInterface進(jìn)行查詢了,如下:

復(fù)制代碼 代碼如下:

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

完整的例子

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

總結(jié)

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

相關(guān)文章

  • C++實(shí)現(xiàn)LeetCode(161.一個(gè)編輯距離)

    C++實(shí)現(xiàn)LeetCode(161.一個(gè)編輯距離)

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(161.一個(gè)編輯距離),本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • 用代碼和UML圖化解設(shè)計(jì)模式之橋接模式的深入分析

    用代碼和UML圖化解設(shè)計(jì)模式之橋接模式的深入分析

    本篇文章是對橋接模式進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • C++標(biāo)準(zhǔn)庫bitset類型的簡單使用方法介紹

    C++標(biāo)準(zhǔn)庫bitset類型的簡單使用方法介紹

    這篇文章主要介紹了C++標(biāo)準(zhǔn)庫bitset類型的簡單使用方法,需要的朋友可以參考下
    2017-07-07
  • c++11多線程編程之std::async的介紹與實(shí)例

    c++11多線程編程之std::async的介紹與實(shí)例

    這篇文章主要給大家介紹了關(guān)于c++11多線程編程之std::async的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • VC++6.0中創(chuàng)建C++項(xiàng)目的實(shí)現(xiàn)步驟

    VC++6.0中創(chuàng)建C++項(xiàng)目的實(shí)現(xiàn)步驟

    本文主要介紹了VC++6.0中創(chuàng)建C++項(xiàng)目的實(shí)現(xiàn)步驟,文中通過圖文介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-03-03
  • C++使用ZLIB庫實(shí)現(xiàn)目錄壓縮與解壓功能

    C++使用ZLIB庫實(shí)現(xiàn)目錄壓縮與解壓功能

    在軟件開發(fā)和數(shù)據(jù)處理中,對數(shù)據(jù)進(jìn)行高效的壓縮和解壓縮是一項(xiàng)重要的任務(wù),這不僅有助于減小數(shù)據(jù)在網(wǎng)絡(luò)傳輸和存儲(chǔ)中的占用空間,還能提高系統(tǒng)的性能和響應(yīng)速度,本文將介紹如何使用 zlib 庫進(jìn)行數(shù)據(jù)的壓縮和解壓縮,以及如何保存和讀取壓縮后的文件
    2025-02-02
  • C++使用模板實(shí)現(xiàn)單鏈表

    C++使用模板實(shí)現(xiàn)單鏈表

    這篇文章主要為大家詳細(xì)介紹了C++使用模板實(shí)現(xiàn)單鏈表,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-12-12
  • C語言實(shí)現(xiàn)數(shù)獨(dú)游戲的求解

    C語言實(shí)現(xiàn)數(shù)獨(dú)游戲的求解

    這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)數(shù)獨(dú)游戲的求解,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • C++ OpenCV學(xué)習(xí)之圖像像素值統(tǒng)計(jì)

    C++ OpenCV學(xué)習(xí)之圖像像素值統(tǒng)計(jì)

    在圖像分析的時(shí)候,我們經(jīng)常需要對單通道圖像的像素進(jìn)行統(tǒng)計(jì)。本文將主要介紹利用C++ OpenCV實(shí)現(xiàn)的圖像像素值統(tǒng)計(jì)的幾種方法,需要的可以參考一下
    2022-01-01
  • 詳解C++?STL模擬實(shí)現(xiàn)vector

    詳解C++?STL模擬實(shí)現(xiàn)vector

    這篇文章主要為大家詳細(xì)介紹了C++如何模擬實(shí)現(xiàn)STL容器vector,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)C++有一定幫助,需要的可以參考一下
    2023-01-01

最新評論

泰州市| 临汾市| 宽甸| 宜宾县| 汶上县| 南华县| 蓬莱市| 宜良县| 兰溪市| 丰镇市| 花莲市| 青龙| 区。| 康保县| 武夷山市| 轮台县| 时尚| 普兰店市| 富锦市| 定远县| 五河县| 石城县| 苏尼特右旗| 霍山县| 苍山县| 永丰县| 朝阳市| 双柏县| 柘荣县| 丰宁| 郴州市| 阿拉善右旗| 鄯善县| 枣阳市| 寿阳县| 龙山县| 秦皇岛市| 曲靖市| 磐石市| 天柱县| 繁峙县|