天天看點

C++ COM程式設計-COM程式設計入門實踐

1. COM程式設計基礎

COM是一種規範,而不是實作。

當使用C++來實作時,COM元件就是一個C++類,而COM接口就是繼承至IUnknown的純虛類,COM元件就是實作相應COM接口的C++類。

COM規範規定,任何元件或接口都必須從IUnknown接口中繼承而來。IUnknown定義了3個重要函數,分别是QueryInterface、AddRef和Release。其中,QueryInterface負責元件對象上的接口查詢,AddRef用于增加引用計數,Release用于減少引用計數。引用計數是COM中的一個非常重要的概念,它很好地解決了元件對象地生命周期問題,即COM元件何時被銷毀,以及誰來銷毀地問題。

除了IUnknown接口外,還有另外一個重要地接口,即IClassFactory。COM元件實際上是一個C++類,對于元件地外部使用者來說,這個類名一般不可知,那麼如何建立這個類地的例?由誰來建立?COM規範規定,每個元件都必須實作一個與之對應的類工廠(Class Factory)。類工廠也是一個COM元件,它實作了IClassFactory接口。在IClassFactory的接口函數CreateInstance中,才能使用new操作生成一個COM元件類對象執行個體。

COM元件有3種類型:

① 程序内元件(CLSCTX_INPROC_SERVER)

② 本地程序元件(CLSCTX_LOCAL_SERVER)

③ 遠端元件(CLSCTX_REMOTE_SERVER)

在接口成員函數中,字元串變量必須用Unicode字元指針,這是COM規範的要求。

2. COM元件開發

實作一個COM元件,需要完成以下工作:

COM元件接口

COM元件實作類

COM元件建立工廠

COM元件注冊與取消注冊

本文以一個例子作為說明,COM元件提供了一個SayHello的接口函數,将“Hello COM”列印輸出。

2.1 建立COM元件接口

COM元件接口是一個繼承IUnknown的抽象類:

COM元件類是一個實作了相應COM元件接口的C++類,注意:一個COM元件可以同時實作多個COM接口。

2.3 COM元件建立工廠

對于元件地外部使用者來說,這個COM元件的類名一般不可知,那麼如何建立這個類地執行個體?由誰來建立?COM規範規定,每個元件都必須實作一個與之對應的類工廠(Class Factory)。類工廠也是一個COM元件,它實作了IClassFactory接口。在IClassFactory的接口函數CreateInstance中,才能使用new操作生成一個COM元件類對象執行個體。

2.4 COM元件的注冊

COM元件需要使用regsvr32工具注冊到系統才能被調用,然而COM元件是如何被regsvr32注冊的?一個典型的自注冊COM元件需要提供4個必需的導出函數:

DllGetClassObject:用于獲得類工廠指針

DllCanUnloadNow:系統空閑時會調用這個函數,以确定是否可以解除安裝COM元件

DllRegisterServer:将COM元件注冊到系統資料庫中

DllUnregisterServer:删除系統資料庫中的COM元件的注冊資訊

DLL還有一個可選的入口函數DllMain,可用于初始化和釋放全局變量

DllMain:DLL的入口函數,在LoadLibrary和FreeLibrary時都會調用

導出檔案(Source.def):

生成完後,使用regsvr32注冊到系統中:

3. COM元件使用

COM元件的使用包括:

如何建立COM元件

如何得到元件對象上的接口以及如何調用接口方法

如何管理元件對象(需熟悉COM的引用計數機制)

下面的代碼是最一般的步驟:

下面我們編寫一個用戶端,調用之前寫的COM元件服務:

上面的例子和一般步驟不一緻,少了QueryInterface,是因為預設傳回的就是指定的接口,下面按一般步驟再實作一次:

是直接建立COM元件并擷取接口,還是先建立COM元件得到預設接口再查詢其他的接口,需要具體問題具體分析。

4.COM元件運作機制

一個COM元件從編寫到最終可以被調用,整個運作流程是怎樣的?或者我們再考慮簡單一點,COM元件是如何被調用的?

繼續閱讀