最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

組件對(duì)象模型 1:概述

2022-05-04 16:12 作者:CSDN首席噴子  | 我要投稿

組件對(duì)象模型(Component Object Model)是微軟的組件技術(shù),能夠創(chuàng)建二進(jìn)制可復(fù)用的程序。其問題來源于代碼的復(fù)用機(jī)制,最早的復(fù)用當(dāng)然是源代碼級(jí)別的復(fù)用,這種方法的問題在于:

  1. 必須公開源代碼。

  2. 代碼會(huì)在所有復(fù)用的地方占據(jù)內(nèi)存,假如在100個(gè)進(jìn)程復(fù)用,就要重復(fù)占用100次。

后來出現(xiàn)了動(dòng)態(tài)鏈接庫技術(shù),解決了公開代碼和重復(fù)內(nèi)存占用的問題,但是DLL仍然不是一個(gè)“可復(fù)用組件”,因?yàn)椋?/p>

  1. 由于C++標(biāo)準(zhǔn)沒有規(guī)定ABI,因此不同的編譯器編譯出來的C++程序必然不兼容,甚至同一廠商編譯器的不同版本都不能兼容。

  2. 即使C++編譯器兼容了,DLL依然需要一個(gè)C++編譯器才能使用,如果是VB就不能執(zhí)行。

COM能夠解決ABI的差異性,又能創(chuàng)建不同語言之間的“膠水”,其思路如下:
  1. 不同C++編譯器在C部分的ABI必然是互相兼容的,導(dǎo)致C++ ABI不兼容的主要原因是虛函數(shù)vtbl的處理不一致。既然如此,可以利用抽象類創(chuàng)建接口,宿主程序只負(fù)責(zé)調(diào)用抽象虛函數(shù),具體執(zhí)行交給DLL。

  2. 將膠水代碼的調(diào)用規(guī)則內(nèi)置在系統(tǒng)中,并創(chuàng)建一個(gè)中心化的服務(wù)進(jìn)程(scm),組件登記到注冊(cè)表,并記錄其調(diào)用方法。

1 ?COM標(biāo)準(zhǔn)

COM組件是由一組接口(C++抽象類,指明調(diào)用規(guī)范)和一組實(shí)現(xiàn)類組成的,其基礎(chǔ)接口是IUnknown,實(shí)例如下:

可以看到:

  • 任何接口都必須繼承自IUnknwon。

  • 所有的接口調(diào)用傳參規(guī)則都是__stdcall,并返回一個(gè)用于表示操作狀態(tài)的HRESULT。

  • 接口所有的函數(shù)都必須是虛函數(shù)。

  • COM組件必須手動(dòng)管理內(nèi)存,AddRef函數(shù)用于引用自增1,返回新的引用數(shù),引用數(shù)應(yīng)該是一個(gè)32位無符號(hào)整數(shù)。

  • Release函數(shù)用于引用自減1,返回新的引用數(shù)。

  • QueryInterface函數(shù)用于將IUnknwon變成需要的接口,第一個(gè)參數(shù)是接口ID,第二個(gè)參數(shù)是所需接口的指針。由于查詢必然伴隨一個(gè)新的引用,因此在此處需要調(diào)用AddRef。

2 ?編程實(shí)例

2.1 ?定義接口和實(shí)現(xiàn)類ID

下面以最簡(jiǎn)單的動(dòng)態(tài)鏈接庫COM組件為例進(jìn)行說明。接口和實(shí)現(xiàn)類是根據(jù)一個(gè)128位UUID標(biāo)記的,分別改名為IID和CLSID。首先定義接口和實(shí)現(xiàn)類的ID:

可以到Windows SDK的安裝目錄找到創(chuàng)建IID和CLSID的工具guidgen.exe。

2.2 ?定義接口和實(shí)現(xiàn)類

定義接口和實(shí)現(xiàn)類:

2.3 ?定義類工廠

注意,由于年代問題,類工廠在官方文檔中被稱為“類對(duì)象”(ClassObject),非常迷惑。之所以創(chuàng)建類工廠是因?yàn)閃indows并不知道怎么創(chuàng)建實(shí)現(xiàn)類的對(duì)象,因此需要提供一個(gè)IClassFactory的實(shí)現(xiàn):

2.4 ?導(dǎo)出系統(tǒng)調(diào)用函數(shù)

一個(gè)COM組件至少需要C語言命名模式導(dǎo)出3個(gè)函數(shù):

  • DllCanUnloadNow

  • DllMain

  • DllGetClassObject

這三個(gè)函數(shù)都不需要用戶手動(dòng)調(diào)用,而是由系統(tǒng)在創(chuàng)建組件實(shí)例的時(shí)候調(diào)用的,其作用分別為:

(1)應(yīng)用程序結(jié)束時(shí)判斷是否能夠卸載DLL。

(2)加載DLL時(shí)的事件處理函數(shù)。

(3)創(chuàng)建類工廠。

下面僅描述DllGetClassObject,其函數(shù)簽名為:

一個(gè)實(shí)例實(shí)現(xiàn)如下:

可以看到其作用就是創(chuàng)建一個(gè)類工廠,然后調(diào)用其QueryInterface。不難猜到系統(tǒng)在這里調(diào)用QueryInterface的目的是獲取一個(gè)IClassFactory指針。另外兩個(gè)函數(shù)不需做其它工作:

為了導(dǎo)出函數(shù)還必須創(chuàng)建定義文件,內(nèi)容如下:

編譯,輸出一個(gè)MyCOM.DLL文件。

2.5 ?導(dǎo)入注冊(cè)表

至此,系統(tǒng)仍然不知道到哪里尋找這個(gè)組件。需以管理員權(quán)限到注冊(cè)表的

HKEY_CLASSES_ROOT\CLSID

下面建立一個(gè)名為{CLSID}的項(xiàng),并創(chuàng)建一個(gè)名為InProcServer32的子項(xiàng)。InProcServer32的默認(rèn)值就是DLL文件的路徑,如下圖所示:

將組件導(dǎo)入注冊(cè)表

3 ?客戶端調(diào)用

客戶端實(shí)例代碼如下:

main.h

main.cpp


組件對(duì)象模型 1:概述的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國家法律
广平县| 金山区| 庆阳市| 固阳县| 洪洞县| 汪清县| 滦南县| 阿坝| 谷城县| 西青区| 汉源县| 焉耆| 水城县| 蓝山县| 桃江县| 商丘市| 高阳县| 遂昌县| 丹东市| 喀喇沁旗| 辽宁省| 西充县| 永定县| 吴川市| 县级市| 陈巴尔虎旗| 夏津县| 陕西省| 绥江县| 华坪县| 杭锦旗| 泸西县| 德昌县| 会理县| 元江| 绥德县| 仪征市| 贺州市| 福州市| 云和县| 永善县|