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

COM 自動化與調度介面完整解析:IDispatch、雙重介面、類型庫與 Invoke 參數詳解

     編輯:關於C語言

自動化讓解釋性語言(VBScript、JavaScript)與巨集語言能輕鬆存取 COM 元件。本文深入剖析 IDispatch 介面、調度介面、雙重介面、Invoke 七大參數、屬性與方法對應、類型庫機制與實務呼叫範例。

IDispatch 介面定義

interface IDispatch : IUnknown {
    HRESULT GetTypeInfoCount(UINT *pctinfo);
    HRESULT GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo);
    HRESULT GetIDsOfNames(REFIID riid, OLECHAR **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);
};

核心雙函式:GetIDsOfNames(名稱→DISPID)、Invoke(DISPID→執行)。

調度介面與雙重介面

  • 調度介面:Invoke 實作的一組函式集合,非 vtable 佈局。
  • 雙重介面:繼承 IDispatch 的 COM 介面,成員同時可透過 vtable(早期繫結)與 Invoke(晚期繫結)存取。C++ 用 vtable 高效,腳本語言用 Invoke 彈性。

IDispatch 呼叫三步驟

  1. 取得元件 IDispatch 介面指標(CoCreateInstance + IID_IDispatch)。
  2. 呼叫 GetIDsOfNames 取得目標函式/屬性的 DISPID。
  3. 構造 DISPPARAMS,呼叫 Invoke 執行。

Invoke 七大參數深度解析

參數說明
dispIdMember目標成員的 DISPID
riid保留,必為 IID_NULL
lcid地區識別碼(GetUserDefaultLCID())
wFlags調用類型:DISPATCH_METHOD、DISPATCH_PROPERTYGET、DISPATCH_PROPERTYPUT、DISPATCH_PROPERTYPUTREF
pDispParams參數陣列(rgvarg),引數順序反向(最右參數在索引 0)
pVarResult接收回傳值/屬性值的 VARIANT 指標,無回傳可為 NULL
pExcepInfo例外資訊結構(wCode/scode、bstrDescription 等),錯誤時填充
puArgErr參數錯誤索引(對應 DISP_E_PARAMNOTFOUND/TYPEMISMATCH)

IDL 中屬性定義與 wFlags 對應

[propput] HRESULT Visible([in] VARIANT_BOOL bVisible);
[propget] HRESULT Visible([out, retval] VARIANT_BOOL *pbVisible);
  • MIDL 產生 put_Visible、get_Visible,同一 DISPID。
  • Invoke 以 wFlags 區分:PROPERTYPUT 呼叫 put、PROPERTYGET 呼叫 get。

類型庫

  • IDL 編譯產物(.tlb),含元件/介面/方法/屬性/參數/結構的完整型別資訊。
  • 可獨立發布(regtlib 註冊)或嵌入 DLL/EXE 資源。
  • C++ 客戶端用 #import "xxx.tlb" no_namespace 產生 .tlh/.tli 標頭,實現早期繫結與智慧提示。

實務建議

  • 純 C/C++ 客戶端 → 直接用 vtable 介面(效能最佳)。
  • 需支援 VB/JS/腳本語言 → 實作雙重介面(dual 介面)。
  • 永遠優先使用類型庫(#import),避免手工構造 DISPPARAMS 易錯。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved