首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

COM 原理與應用:自動化物件與 IDispatch 介面

     編輯:關於C++

自動化技術定位

  • 建立於 COM 基礎,繼承語言無關、進程透明優點。
  • 簡化 COM 底層細節:屬性/方法處理、專用資料類型 (VARIANT)。
  • 核心介面:IDispatch,每個自動化物件必須實作。
  • OLE 基礎,可運行於 DLL/EXE 元件,支援 DCOM 遠端建立/連接。

發展動機

  • COM 對弱型別語言 (VB、VBScript、JavaScript) 支援不足。
  • 自動化提供直觀、友善的跨語言通訊途徑:符號名稱存取屬性/方法、晚期繫結。
  • Visual Basic / VBA 成功推動自動化普及,成為 Office 巨集、腳本開發標準。

屬性與方法

  • 屬性:資料特徵,可 Get/Set(本質是值)。
  • 方法:功能服務,0~多參數,可 Get/Set 資料或執行動作。
  • 皆有符號化名稱,客戶端透過名稱存取。

型別庫與 ODL

  • 型別資訊:CLSID、介面 IID、方法、參數/回傳型別、自訂結構/聯合/列舉。
  • ODL (Object Description Language):擴充 IDL,interface/dispinterface 描述介面,coclass 描述物件,library 定義型別庫資訊 (LIBID、版本、語言)。
  • MIDL / MkTypLib 編譯 ODL 產生 .tlb 型別庫 與 .h 頭檔。
  • 用途:VB/VBA 瀏覽物件、增強存取;IDispatch 實作時利用型別庫避免繁瑣型別處理。

IDispatch 介面核心

interface IDispatch : IUnknown {
    HRESULT GetTypeInfoCount(UINT* pctinfo);
    HRESULT GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo);
    HRESULT GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, UINT cNames,
                          LCID lcid, DISPID* rgDispId);
    HRESULT Invoke(DISPID dispIdMember, REFIID riid, LCID lcid,
                   WORD wFlags, DISPPARAMS* pDispParams,
                   VARIANT* pVarResult, EXCEPINFO* pExcepInfo,
                   UINT* puArgErr);
};
  • Invoke:關鍵函數,所有屬性/方法存取皆透過它 → 「自動化物件的指令翻譯器」。
  • GetIDsOfNames:名稱 → DISPID (分派識別碼)。
  • GetTypeInfo:提供型別資訊供瀏覽/早期繫結。

自動化相容資料類型:VARIANT

  • VARIANT (16 位元組) 封裝所有自動化支援型別:整數、浮點、字串 (BSTR)、布爾、日期、貨幣、陣列 (SAFEARRAY)、物件介面、錯誤碼、空值等。
  • VARIANTARG 用於參數傳遞。

IDispatchEx:動態型別資訊

  • IDispatch 型別資訊靜態 (編譯期固定)。
  • 腳本語言需執行期動態增減成員 → IDispatchEx 繼承 IDispatch,支援動態型別資訊。

自動化物件實作關鍵

  1. 型別庫支援:利用 ITypeInfo 實作 Invoke,自動處理參數封送/型別轉換。
  2. Invoke 實作:手寫分派邏輯(switch(dispid))或使用 CreateStdDispatch 標準分派器。
  3. 例外處理:EXCEPINFO 回傳豐富錯誤資訊。
  4. 多語系/本地化:型別庫支援多語言名稱/說明。

雙重介面:效率與便利並存

  • 問題:IDispatch::Invoke 間接呼叫、多層處理、效率損失大。
  • 解法:雙重介面 = IDispatch + 自訂 vtable 介面 暴露同樣方法/屬性。
  • 早期繫結客戶端直接呼叫 vtable 方法(高效);晚期繫結客戶端用 IDispatch(便利)。
  • ODL 中用 dual 關鍵字定義。

早期繫結 vs 晚期繫結

繫結方式機制效率適用環境
早期繫結編譯期用型別庫檢查型別,直接用 DISPID 呼叫 Invoke高VB/VBA 專案引用型別庫、C++ 智慧指標
晚期繫結執行期 GetIDsOfNames 解析名稱 → DISPID → Invoke低VBScript、JavaScript、動態語言、Run-time 動態載入
選擇取決於控制器運行環境,非以效率為唯一判斷。

自動化集合物件

  • 同類物件/值的容器,需支援:Count 屬性、Item(index)、Add/Remove、列舉器 (_NewEnum / IEnumVARIANT)。

IDispatch 作為輸出介面

  • 可連接物件的輸出介面採用 IDispatch,利用 Invoke 統一分派事件,解決動態接收器建立難題。
  • COM 已提供 IDispatch Proxy/Stub,支援跨進程事件。

MFC 自動化支援

  • COleDispatchDriver:客戶端封裝,簡化 Invoke 參數處理,支援建立/連接自動化物件。
  • Visual Basic 中直接 CreateObject / GetObject 使用自動化物件。

總結

自動化技術以 IDispatch + VARIANT + 型別庫為核心,為弱型別腳本語言與元件互操作提供標準橋樑。雙重介面兼顧效率與便利,早期/晚期繫結適應不同開發環境。MFC/COleDispatchDriver 進一步簡化 C++ 客戶端開發。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved