国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

COM編程入門1

2019-11-17 05:45:18
字體:
來源:轉載
供稿:網友

  COM編程入門(1)

    本文的目的是為剛剛接觸COM的程序員提供編程指南,并幫助他們理解COM的基本概念。內容包括COM規范簡介,重要的COM術語以及如何重用現有的COM組件。本文不包括如何編寫自己的COM對象和接口。
        COM即組件對象模型,是Component Object Model 取前三個字母的縮寫,這三個字母在當今Windows的世界中隨處可見。隨時涌現出來的大把大把的新技術都以COM為基礎。各種文檔中也充斥著諸如COM對象、接口、服務器之類的術語。因此,對于一個程序員來說,不僅要把握使用COM的方法,而且還要徹底熟悉COM的所有一切。
    本文由淺入深描述COM的內在運行機制,教你如何使用第三方提供的COM對象(以Windows 外殼組件Shell為例)。讀完本文后,你就能把握如何使用Windows操作系統中內建的組件和第三方提供的COM對象。
    本文假設你精通C++語言。在例子代碼中使用了一點MFC和ATL,假如你不熟悉MFC和ATL也沒關系,本文會對這些代碼進行完全透徹的解釋。
本文包括以下幾個部分:
COM——到底是什么?——COM標準的要點介紹,它被設計用來解決什么問題?
基本元素的定義——COM術語以及這些術語的含義。
使用和處理COM對象——如何創建、使用和銷毀COM對象。
基本接口——描述IUnknown基本接口及其方法。
把握串的處理——在COM代碼中如何處理串。
應用COM技術——例子代碼,舉例說明本文所討論的所有概念。
處理HRESULT——HRESULT類型描述,如何監測錯誤及成功代碼。

COM——到底是什么?
    簡單地說,COM是一種跨應用和語言共享二進制代碼的方法。與C++不同,它提倡源代碼重用。ATL便是一個很好的例證。源碼級重用雖然好,但只能用于C++。它還帶來了名字沖突的可能性,更不用說不斷拷貝重用代碼而導致工程膨脹和臃腫。
      Windows使用DLLs在二進制級共享代碼。這也是Windows程序運行的要害——重用kernel32.dll, user32.dll等。但DLLs是針對C接口而寫的,它們只能被C或理解C調用規范的語言使用。由編程語言來負責實現共享代碼,而不是由DLLs本身。這樣的話DLLs的使用受到限制。
MFC引入了另外一種MFC擴展DLLs二進制共享機制。但它的使用仍受限制——只能在MFC程序中使用。
       COM通過定義二進制標準解決了這些問題,即COM明確指出二進制模塊(DLLs和EXEs)必須被編譯成與指定的結構匹配。這個標準也確切規定了在內存中如何組織COM對象。COM定義的二進制標準還必須獨立于任何編程語言(如C++中的命名修飾)。一旦滿足了這些條件,就可以輕松地從任何編程語言中存取這些模塊。由編譯器負責所產生的二進制代碼與標準兼容。這樣使后來的人就能更輕易地使用這些二進制代碼。
    在內存中,COM對象的這種標準形式在C++虛函數中偶然用到,所以這就是為什么許多COM代碼使用C++的原因。但是記住,編寫模塊所用的語言是無關的,因為結果二進制代碼為所有語言可用。
    此外,COM不是Win32特有的。從理論上講,它可以被移植到Unix或其它操作系統。但是我似乎還從來沒有在Windows以外的地方聽說過COM。
基本元素的定義
    我們從下往上看。接口只不過是一組函數。這些函數被稱為方法。接口名字以大寫的I開頭,例如C++中的IShellLink,接口被設計成一個抽象基類,其中只有純粹的虛擬函數。
    接口可以從其它接口繼續,這里所說的繼續的原理就似乎C++中的單繼續。接口是不答應多繼續的。
       coclass(簡稱組件對象類——component object class)被包含在DLL或EXE中,并且包含著一個或者多個接口的代碼。組件對象類(coclasss)實現這些接口。COM對象在內存中表現為組件對象類(coclasss)的一個實例。注重COM“類”和C++“類”是不相同的,盡管經常COM類實現的就是一個C++類。
     COM服務器是包含了一個或多個coclass的二進制(DLL或EXE)。
注冊(Registration)是創建注冊表入口的一個過程,告訴Windows 操作系統COM服務器放在什么位置。取消注冊(Unregistration)則相反——從注冊表刪除這些注冊入口。

    GUID(諧音為“fluid”,意思是全球唯一標示符——globally unique identifier)是個128位的數字。它是一種獨立于COM編程語言的標示方法。每一個接口和coclass有一個GUID。因為每一個GUID都是全球唯一的,所以避免了名字沖突(只要你用COM API創建它們)。有時你還會碰到另一個術語UUID(意思也是全球唯一標示符——universally unique identifier)。UUIDs和GUIDs在實際使用時的用途是一樣的。
    類ID或者CLSID是命名coclass的GUID。接口ID或者IID是命名接口的GUID。
在COM中廣泛地使用GUID有兩個理由:
1、GUIDs只是簡單的數字,任何編程語言都可以對之進行處理。
2、GUIDs可以在任何機器上被任何人創建,一旦完成創建,它就是唯一的。因此,COM開發人員可以創建自己特有的GUIDs而不會與其它開發人員所創建的GUIDs有沖突。這樣就消除了集中授權發布GUIDs的必要。
HRESULT是COM用來返回錯誤和成功代碼的整型數字。除此之外,別無它意,雖然以H作前綴,但沒有句柄之意。下文會對它有更多的討論。
最后,COM庫是在你使用COM時與你交互的操作系統的一部分,它經常指的就是COM本身。但是為了避免混淆才分開描述的。
使用和處理COM對象
    每一種語言都有其自己處理對象的方式。例如,C++是在棧中創建對象,或者用new動態分配。因為COM必須獨立于語言,所以COM庫為自己提供對象治理例程。下面是對COM對象治理和C++對象治理所做的一個比較:
創建一個新對象
    C++中,用new操作符,或者在棧中創建對象。
    COM中,調用COM庫中的API。
刪除對象
    C++中,用delete操作符,或將棧對象踢出。
    COM中,所有的對象保持它們自己的引用計數。調用者必須通知對象什么時候用完這個對象。當引用計數為零時,COM對象將自己從內存中釋放。
    由此可見,對象處理的兩個階段:創建和銷毀,缺一不可。當創建COM對象時要通知COM庫使用哪一個接口。假如這個對象創建成功,COM庫返回所請求接口的指針。然后通過這個指針調用方法,就像使用常規C++對象指針一樣。
創建COM對象
    為了創建COM對象并從這個對象獲得接口,必須調用COM庫的API函數,CoCreateInstance()。其原型如下:
HRESULT CoCreateInstance (
    REFCLSID  rclsid,
    LPUNKNOWN pUnkOuter,
    DWord     dwClsContext,
    REFIID    riid,
    LPVOID*   ppv );

以下是參數解釋:
rclsid
coclass的CLSID,例如,可以傳遞CLSID_ShellLink創建一個COM對象來建立快捷方式。
pUnkOuter
這個參數只用于COM對象的聚合,利用它向現有的coclass添加新方法。參數值為null表示不使用聚合。
dwClsContext
表示所使用COM服務器的種類。本文使用的是最簡單的COM服務器,一個進程內(in-PRocess)DLL,所以傳遞的參數值為CLSCTX_INPROC_SERVER。注重這里不要隨意使用CLSCTX_ALL(在ATL中,它是個缺省值),因為在沒有安裝DCOM的Windows95系統上會導致失敗。
riid
請求接口的IID。例如,可以傳遞IID_IShellLink獲得IShellLink接口指針。
ppv
接口指針的地址。COM庫通過這個參數返回請求的接口。
當你調用CoCreateInstance()時,它負責在注冊表中查找COM服務器的位置,將服務器加載到內存,并創建你所請求的coclass實例。
以下是一個調用的例子,創建一個CLSID_ShellLink對象的實例并請求指向這個對象IShellLink接口指針。
HRESULT     hr;
IShellLink* pISL;

    hr = CoCreateInstance ( CLSID_ShellLink,         // coclass 的CLSID
                            NULL,                    // 不是用聚合

                            CLSCTX_INPROC_SERVER,    // 服務器類型
                     

上一篇:backdoor病毒源代碼

下一篇:COM編程入門2

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 洪雅县| 耿马| 武陟县| 光山县| 丹江口市| 扶沟县| 耿马| 肇州县| 万盛区| 晋中市| 老河口市| 黄浦区| 蕲春县| 兴宁市| 曲松县| 永善县| 蛟河市| 四子王旗| 邹平县| 勃利县| 富裕县| 勐海县| 中牟县| 尼木县| 东乌珠穆沁旗| 潜江市| 蓬莱市| 类乌齐县| 湘潭市| 荔波县| 定襄县| 武宁县| 利川市| 白沙| 西贡区| 策勒县| 县级市| 章丘市| 西青区| 仙游县| 恭城|