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

C# 與 C++ 互相呼叫 (二):C++ 呼叫 C# COM+ 元件完整實作

     編輯:關於C#

架構決策

核心演算法用 C++ (難逆向),其餘層 (UI、資料存取) 用 C#。上篇完成 C# 呼叫 C++ DLL,本篇完成 C++ 呼叫 C#,採 COM+ (ServicedComponent) 方案:C# 暴露 COM 介面,C++ 透過 `#import` 智慧指標呼叫。

C# 端:建立 COM+ 元件

1. 專案設定

  • 專案類型:類別庫 (Class Library)
  • AssemblyInfo.cs 關鍵屬性:
    
    [assembly: ComVisible(true)]
    [assembly: Guid("94882155-3B7C-48e3-B357-234D56D8F15E")] // 類型庫 ID
    
  • 專案屬性 → 建置 → 勾選「登錄 COM Interop」
  • 簽署強名稱金鑰 (SN.exe)

2. 介面與實作


using System;
using System.EnterpriseServices;
using System.Runtime.InteropServices;

namespace ComInteropDemo {
    // 介面:需 Guid、DispId
    [Guid("7103C10A-2072-49fc-AD61-475BEE1C5FBB")]
    public interface IComInterop {
        [DispId(1)] int Add(int a, int b);
        [DispId(2)] int Minus(int a, int b);
    }

    // 實作:繼承 ServicedComponent、ClassInterfaceType.None
    [Guid("87796E96-EC28-4570-90C3-A395F4F4A7D6")]
    [ClassInterface(ClassInterfaceType.None)]
    public class ComInterop : ServicedComponent, IComInterop {
        public int Add(int a, int b) => a + b;
        public int Minus(int a, int b) => a - b;
    }
}

3. 註冊與類型庫匯出


# 開發機命令列 (VS Developer Command Prompt)
regasm ComInteropDemo.dll /tlb:ComInteropDemo.tlb /codebase
# 重新編譯前需先解除註冊
regasm /u ComInteropDemo.dll

關鍵規則

  • 所有公開成員必須在介面定義 (含事件介面),否則 C++ 無法透過 vtable 呼叫。
  • 介面方法必須標 `[DispId(N)]`,確保 vtable 位置固定。
  • 專案必須啟用 COM Interop 且強名稱簽署。
  • `ComVisible` 預設 `false`,務必在 AssemblyInfo 設 `true`。

C++ 端:呼叫 COM+ 元件

1. 專案建立

  • Win32 主控台應用程式
  • 專案屬性 → C/C++ → 一般 → 附加包含目錄加入 `$(ProjectDir)..\ComInteropDemo\Debug` (含 .tlb)

2. 程式碼


#include "stdafx.h"
#include 
using namespace std;

#import "..\\Debug\\ComInteropDemo.tlb" no_namespace named_guids
// 路徑依專案相對位置調整

int _tmain(int argc, _TCHAR* argv[]) {
    HRESULT hr;
    CoInitialize(NULL); // 初始化 COM 庫

    // 建立介面智慧指標
    ComInteropDemo::IComInteropPtr ptr;

    // 建立 COM 物件實例
    hr = ptr.CreateInstance(__uuidof(ComInteropDemo::ComInterop));
    if (SUCCEEDED(hr)) {
        cout << "Add(1,2) = " << ptr->Add(1, 2) << endl; // 輸出 3
    } else {
        cerr << "CreateInstance failed: 0x" << hex << hr << endl;
    }

    CoUninitialize(); // 釋放 COM
    return 0;
}

編譯鍵

  • `#import` 產生智慧指標 `*Ptr`、 `__uuidof`、包裝類別。
  • `CoInitialize/CoUninitialize` 配對呼叫 (單執行緒模式 STA)。
  • 若部署至無 VS 機器,需手動 `regasm /tlb` 註冊組件。

COM+ 方案讓 C++ 以原生方式呼叫 C# 邏輯,適合「核心 C++、周邊 C#」架構。生產環境建議:介面版本管理、錯誤代碼標準化、效能基準測試 (COM 封送開銷)。

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