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

C# COM 互操作基礎(一):四種建立 COM 物件方式比較

     編輯:關於C#

.NET 與 COM 互操作時,建立 COM 物件有四種主要方式,各有適用場景與優缺點。本文系統比較:匯入類型庫 (TLB)、反射晚期繫結、P/Invoke CoCreateInstance、自訂 ComImport 類別。

方式一:匯入類型庫 (Visual Studio 嵌入互操作組件)

  • 操作:專案 → 加入參考 → COM → 選擇元件 (如 Microsoft Word 16.0 Object Library)。
  • 產生 Interop.XXX.dll (或內嵌型別資訊),提供強型別包裝。
  • 優點:IntelliSense 完整、編譯期型別檢查、開發效率最高。
  • 缺點:版本綁定 — 開發機 Word 16.0,目標機 Word 14.0 可能執行失敗 (缺少介面/方法)。僅支援雙重介面 (IDispatch/Dual)。

方式二:反射晚期繫結


Type t = Type.GetTypeFromCLSID(new Guid("DE88C160-FF2C-11D1-BB6F-00C04FAE22DA")); // JetEngine
// 或 Type.GetTypeFromProgID("JRO.JetEngine");
object comObj = Activator.CreateInstance(t);
// 呼叫方法
t.InvokeMember("CompactDatabase", BindingFlags.InvokeMethod, null, comObj, new object[] { src, dest });
  • 優點:不需匯入 TLB,僅需 CLSID/ProgID;版本適應性強,執行期動態綁定。
  • 缺點:無 IntelliSense、效能較低 (反射調用)、拼錯方法名只能執行期發現。

方式三:P/Invoke CoCreateInstance


[DllImport("ole32.dll", ExactSpelling = true, PreserveSig = false)]
static extern void CoCreateInstance(ref Guid clsid, IntPtr punkOuter, uint context, ref Guid iid, out IntPtr ppv);

Guid clsid = new Guid("DE88C160-FF2C-11D1-BB6F-00C04FAE22DA");
Guid iid = new Guid("9F63D980-FF25-11D1-BB6F-00C04FAE22DA"); // IJetEngine
CoCreateInstance(ref clsid, IntPtr.Zero, 1 /*CLSCTX_INPROC_SERVER*/, ref iid, out IntPtr pJet);
// 需手動 Marshal.GetObjectForIUnknown(pJet) 轉 RCW
  • 優點:參數控制最靈活 (CLSCTX、聚合、特定介面)。
  • 缺點:繁瑣、易錯、需手動管理指標與參考計數、非 .NET 風格。

方式四:自訂 ComImport 類別 (推薦用於簡單 COM)


[ComImport, Guid("DE88C160-FF2C-11D1-BB6F-00C04FAE22DA")]
class JetEngineClass { } // 空類別,僅作建立入口

[ComImport, CoClass(typeof(JetEngineClass)), Guid("9F63D980-FF25-11D1-BB6F-00C04FAE22DA")]
interface IJetEngine
{
    void CompactDatabase([In, MarshalAs(UnmanagedType.BStr)] string src,
                         [In, MarshalAs(UnmanagedType.BStr)] string dest);
    void RefreshCache([In, MarshalAs(UnmanagedType.Interface)] object conn);
}

// 使用
JetEngineClass engine = new JetEngineClass(); // CLR 依 Guid 建立 COM 物件
IJetEngine jet = engine as IJetEngine; // 查詢介面
jet.CompactDatabase("src.mdb", "dest.mdb");
  • 優點:純 .NET 語法 (new、as)、無額外組件、版本鬆耦合 (僅需 GUID 相容)、支援自訂介面子集。
  • 缺點:需手寫介面定義、不支援事件/複雜介面層級、複雜 COM 定義維護成本高。

RCW 類型身分差異 (四種方式建立的物件)

  • 方式一:強型別包裝類別 (如 Word.ApplicationClass)
  • 方式二/三/四:System.__ComObject (晚期繫結 RCW)

但同一 COM 物件的不同介面查詢結果,皆為同一 RCW 實例 (CLR 內部快取)。

選擇建議

場景推薦方式
Office 自動化、複雜型別庫、團隊開發方式一 (匯入 TLB) + 內嵌互操作類型
簡單 COM、無型別庫、版本不固定、輕量部署方式四 (ComImport)
動態載入未知 COM、外掛架構方式二 (反射)
需精確控制 CLSCTX、聚合、特定介面指標方式三 (CoCreateInstance)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved