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

COM 組件設計實戰:多介面實作與版本升級策略

     編輯:關於C語言

本文實戰演示如何使用 ATL 實作支援多個自訂介面的 COM 組件,並闡述符合 COM 規範的介面升級策略(不可修改已發布介面,需新增介面擴充功能)。

設計原則:介面職責單一化

  • 單一介面函數數量建議 ≤ 7(人類短期記憶極限),功能聚焦易學易用。
  • 維護性佳:介面職責清晰,程式碼搜尋修改效率高。
  • 升級相容:嚴禁修改已發布介面,新功能透過新介面(如 IMathe2)提供,舊用戶繼續使用 IMathe,新用戶享受完整功能。

實作流程:從單一介面擴充至多介面

步驟 1:建立基礎組件(IMathe)

使用 ATL 精靈建立自訂介面 IMathe,含 Add(long, long, long*) 整數加法函式。必須為自訂介面,非雙重介面。

步驟 2:檢視與理解 IDL 定義

interface IMathe : IUnknown {
    [helpstring("method Add")] HRESULT Add([in] long n1, [in] long n2, [out,retval] long *pnVal);
};

coclass Mathe {
    [default] interface IMathe;
};

關鍵點:UUID 為介面唯一識別(IID),coclass 區塊宣告元件支援的介面清單,[default] 標示預設提供 IUnknown 的介面。

步驟 3:手動修改 IDL 新增第二介面 (IStr)

[object, uuid(072EA6CB-...), helpstring("IStr Interface"), pointer_default(unique)]
interface IStr : IUnknown {
    // 暫無函式,後續添加
};

同步更新 coclass 區塊:

coclass Mathe {
    [default] interface IMathe;
    interface IStr;  // 新增介面聲明
};

步驟 4:修改 C++ 標頭檔,更新繼承與 COM Map

class ATL_NO_VTABLE CMathe :
    public CComObjectRootEx,
    public CComCoClass,
    public IMathe,
    public IStr  // 新增基底介面
{
    BEGIN_COM_MAP(CMathe)
        COM_INTERFACE_ENTRY(IMathe)
        COM_INTERFACE_ENTRY(IStr)  // 註冊介面入口
    END_COM_MAP()
};

步驟 5:於新介面添加功能函式

於 IStr 添加字串連接函式:

HRESULT Cat([in] BSTR s1, [in] BSTR s2, [out,retval] BSTR *psVal);

介面升級實戰:新增 IMathe2 擴充數學功能

組件已發布,需新增乘法 Mul()。不可修改 IMathe,解決方案:

  1. 於 IDL 定義新介面 IMathe2 : IUnknown,包含 Add() 與新增的 Mul()。
  2. 更新 coclass 註冊 interface IMathe2;。
  3. C++ 類別繼承 public IMathe2 並加入 COM_INTERFACE_ENTRY(IMathe2)。
  4. 實作 IMathe2::Mul(),Add() 可轉呼叫既有實作或重新實作。

此策略確保二進位相容:舊用戶透過 QueryInterface(IID_IMathe) 繼續工作,新用戶透過 QueryInterface(IID_IMathe2) 獲得擴充功能。

核心原則總結

COM 介面不變原則:一旦發布,介面定義凍結。功能擴充唯一正途——新增介面。此為 COM 元件長期演進的基石。

相關工具

  • guidgen.exe:產生新介面/元件 UUID。
  • IDL 編輯器:Visual Studio 內建支援。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved