com進程內進程外組件

來源:互聯網
上載者:User
COM進程內組件與進程外組件1.   COM進程內組件

進程內組件以動態連結程式庫的形式存在(尾碼名為dll),用戶端需要使用進程內組件提供的服務時只需要將dll載入進用戶端進程。進程內組件必須提供自註冊功能,這樣用戶端進程才能在需要的從註冊表中尋找到相應的資訊,並載入該組件。

 

進程內組件需要匯出四個函數

DllRegisterServer:

參數:無

傳回值:HRESULT 指示註冊操作的錯誤類型

 

DllUnregisterServer

參數:無

傳回值:HRESULT 指示刪除註冊表中的相應項操作的錯誤類型

 

DllGetClassObject

參數1:CLSID&組件的CLSID(因為一個dll可以作為多個組件的載體)

參數2:IID&,要從組件中擷取的介面IID

參數3:void**,接收穫得的介面指標的雙重指標

傳回值: HRESULT 指示操作結果的錯誤類型,一般有(E_OUTOFME\

MORY, S_OK,E_NOINTERFACE,CLASS_E_CLASSNOTAVAILABLE);

DllCanUnloadNow

參數:無

傳回值:HRESULT 指示是否可卸載該組件

說明:COM庫每隔一段時間便會自動調用該方法判斷是否可以卸載該組件。

 

進程內組件註冊表中需要的內容

位於HKEY_CLASSES_ROOT的CLSID項下

其中7F21137D…為組件的CLSID

InprocServer32所對應的值為進程內組件的完整路徑

ProgID 所對應的值為組件的自訂名稱用戶端可以通過該名稱獲得組件的CLSID.

 

2.COM進程外組件2.1  LPC和RPC

COM採用LPC(本地程序呼叫)和RPC(遠端程序呼叫)的方法進行進程之間的通訊,LPC用於在同一機器上的不同進程之間進行通訊,而RPC用於在不同機器上的進程之間進行通訊。

2.2 存根代理dll

為了提供LPC的處理,com提供了一個非常簡便的方法,當組件為進程外組件時,客戶將同一個模仿組件的dll進行通訊,這個dll可以為客戶完成參數調整以及LPC調用,這個dll在用戶端稱之為代理dll,而在伺服器端稱作為存根dll。

代理存根dll的產生步驟:

 

1. 編寫idl檔案

該idl檔案包含了所有服務端組件定義的介面,組件標示符CLSID除外

2. 使用MIDL編譯該IDL檔案

編譯後產生的一下幾個檔案

1) XXX_h.h   包含介面定義的標頭檔,和所有介面IID的聲明

2) XXX_i.c   介面IID的定義

3) XXX_p.c   代理檔案

4) Dlldata.c 資料檔案

3. 使用以上檔案產生存根代理dll

1)  在預先處理增加REGISTER_PROXY_DLL

2)  提供輸入庫rpcrt4.lib   uuid.lib

3)  添加def檔案,匯出五個函數

4)  編譯產生dll

產生後的dll會有五個匯出函數如

 

前面四個和進程內組件意義一致

 

2.3  進程外組件的註冊

進程外組件註冊需要註冊存根代理dll和組件exe檔案,其中存根代理dll的註冊和進程內組件的註冊一致,而exe檔案的註冊就依靠其命令參數來進行。

組件程式的兩個用於註冊的入口函數為DllRegisterServer和DllUnregisterServer,註冊組件使用命令:RegSvr32
*.dll;反註冊組件使用命令:RegSvr32 /u *.dll,進程內組件註冊使用此命令。進程外組件註冊必須支援兩個命令列參數/RegServer和/UnregServer。

CLSID子鍵下:

圖1

 

圖2

Interface子鍵下:

圖3

圖4

 

其中ProxyStubClsid32為該介面的存根代理dll的CLSID,圖1,這樣在查詢某介面時com庫就知道到哪載入存根代理dll了

3 類廠

COM庫通過類廠建立COM對象,對應每一個COM類,都有一個類廠專門用於該COM類的對象建立工作。類廠本身也是一個COM對象,它支援介面IClassFactory。

CreateInstance建立對應的COM對象,LockServer控制組件的生存周期。

類廠由函數DllGetClassObject建立。

DllGetClassObject返回類廠對象的介面指標,再通過CreateInstance建立對應的COM對象。

4.COM庫與類廠的互動

建立對象函數:

1)若建立遠程對象或希望一次擷取對象的多個介面指標,選用CoCreateInstanceEx。

2)若希望擷取類廠對象或要調用類廠的某些成員函數,選用CoGetClassObject,通常IID=IID_IclassFactory,進程內組件直接調用DLL的CoGetClassObject,若CoGetClassObject建立的類廠對象位於進程外組件,函數啟動組件進程,然後等待,直到組件進程把它支援的COM類對象的類廠註冊到COM中,返回類廠資訊。

3)其他情況下,選用CoCreateInstance建立對象,CoCreateInstance封裝類廠建立對象的過程,返回COM對象的介面指標,不能建立遠程機器上的對象。

 

 


5.COM庫

COM庫初始化函數:CoInitialize

COM庫終止函數:CoUninitialize

COM庫記憶體管理:

COM提供的記憶體管理器標準,是一個COM介面IMalloc。當組件記憶體的分配和釋放不在同一模組,需要用到記憶體管理器,COM庫封裝了三個API函數,用於記憶體配置和釋放

CoTaskMemAlloc

CoTaskMemFree
CoTaskMemRealloc

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.