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

C++/C# 跨語言呼叫 COM 組件完整指南:四種組合模式全覆蓋 (VS2005 + VC6.0)

     編輯:關於VC++

四種跨語言 COM 呼叫矩陣

#COM 組件語言/工具呼叫端語言/工具關鍵技術
1C# (VS2005) Class LibraryC++ (VS2005) /clr#using "xxx.dll" + gcnew
2C# (VS2005) COM VisibleC++ (VC6.0) MFC#import "xxx.tlb" + 智慧指標
3C++ (VC6.0) ATL COMC# (VS2005) ASP.NET加入 COM 參考 + out 參數
4C++ (VC6.0) ATL COMC++ (VC6.0) MFC#import "xxx.dll" + CreateInstance

模式 1:C# DLL → C++/CLI (VS2005)

C# 類庫


namespace AddDll {
    public class Add {
        public int iadd(int a, int b) { return a + b; }
    }
}

C++/CLI 消費者

  • 專案屬性 → Common Language Runtime Support: /clr
  • #using "..\debug\AddDll.dll"
  • using namespace AddDll;
  • Add^ add = gcnew Add(); int r = add->iadd(10, 90);

模式 2:C# COM → VC6.0 MFC

C# COM 組件 (關鍵設定)

  • 專案屬性 → Build → Register for COM interop ✓
  • AssemblyInfo.cs:[assembly: ComVisible(true)]
  • 介面/類別標註 [Guid("...")]、[ClassInterface(ClassInterfaceType.None)]、[DispId(n)]
  • 產生 AddCom.tlb (型別程式庫)

[Guid("298D881C-E2A3-4638-B872-73EADE25511C")]
public interface AddComInterface {
    [DispId(1)] int iadd(int a, int b);
    [DispId(2)] float fadd(float a, float b);
}
[Guid("2C5B7580-4038-4d90-BABD-8B83FCE5A467")]
[ClassInterface(ClassInterfaceType.None)]
public class AddComService : AddComInterface { ... }

VC6.0 消費者


// stdafx.h
#import "AddCom.tlb"
using namespace AddCom;

// 使用
CoInitialize(NULL);
AddComInterfacePtr pAdd(__uuidof(AddComService));
int r = pAdd->iadd(1, 2);
float f = pAdd->fadd(1.2f, 2.3f);
CoUninitialize();

模式 3:VC6.0 ATL COM → C# ASP.NET (VS2005)

VC6.0 ATL COM 專案

  • 專案類型:ATL COM AppWizard → DLL
  • IDL 定義介面:
    
    interface IAdd : IDispatch {
        [id(1)] HRESULT iadd([in]int a, [in]int b, [out]int* c);
        [id(2)] HRESULT fadd([in]float a, [in]float b, [out]float* c);
        [id(3)] HRESULT isub([in]int a, [in]int b, [out]int* c);
    };
        
  • 實作:STDMETHODIMP CAdd::iadd(int a, int b, int* c) { *c = a+b; return S_OK; }
  • 編譯註冊:regsvr32 AddCom.dll

C# ASP.NET 消費者

    方案總管 → 加入參考 → COM → AddCom 1.0 Type Library
  • using ADDCOMLib;
  • Add add = new Add(); add.IAdd(10, 20, out int r); add.fadd(1.2f, 2.3f, out float f);

模式 4:VC6.0 ATL COM → VC6.0 MFC (經典雙邊)

MFC 消費者


// stdafx.h
#import "AddCom.dll" no_namespace

// 使用
CoInitialize(NULL);
IAddPtr pAdd;
pAdd.CreateInstance(__uuidof(Add));
int a=90, b=10, c, d;
float fa=1, fb=2, fc;
pAdd->iadd(a, b, &c);
pAdd->fadd(fa, fb, &fc);
pAdd->isub(a, b, &d);
pAdd.Release();
CoUninitialize();

關鍵坑點與最佳實踐

問題解決方案
C# COM 介面需穩定 GuidVisual Studio → Tools → Create GUID → Registry Format → 複製完整 {GUID}
VC6.0 #import 找不到 .tlb/.dll確保檔案在專案目錄或系統路徑;或用完整路徑 #import "C:\\path\\AddCom.tlb"
C# out/ref 對應 IDL [out]IDL 用 [out] int* c,C# 端自動映射為 out int c
跨 AppDomain/序列化COM 物件本質為單元模型,跨界需考慮封送成本
註冊免註冊 (Reg-Free COM)XP+ 支援 Manifest 內嵌,避免系統註冊衝突

總結

四種模式涵蓋了 .NET Framework 1.x/2.0 與 VC6.0 共存遷移期的主流互操作場景。核心原則:

  1. 介面優先:定義穩定的 IDL/介面,實作細節隱藏
  2. Guid 不變:一旦發布不可修改
  3. 錯誤處理:HRESULT ↔ Exception 邊界轉換
  4. 生命週期:CoInitialize/Uninitialize、AddRef/Release、智慧指標

完整原始碼 (四組專案) 請參考本文配套下載。適用於舊系統模組化遷移、.NET 與原生 C++ 混合開發、第三方 COM 組件整合等場景。

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