| # | COM 組件語言/工具 | 呼叫端語言/工具 | 關鍵技術 |
|---|---|---|---|
| 1 | C# (VS2005) Class Library | C++ (VS2005) /clr | #using "xxx.dll" + gcnew |
| 2 | C# (VS2005) COM Visible | C++ (VC6.0) MFC | #import "xxx.tlb" + 智慧指標 |
| 3 | C++ (VC6.0) ATL COM | C# (VS2005) ASP.NET | 加入 COM 參考 + out 參數 |
| 4 | C++ (VC6.0) ATL COM | C++ (VC6.0) MFC | #import "xxx.dll" + CreateInstance |
namespace AddDll {
public class Add {
public int iadd(int a, int b) { return a + b; }
}
}
#using "..\debug\AddDll.dll"using namespace AddDll;Add^ add = gcnew Add(); int r = add->iadd(10, 90);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 { ... }
// 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();
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.dllusing ADDCOMLib;Add add = new Add(); add.IAdd(10, 20, out int r); add.fadd(1.2f, 2.3f, out float f);
// 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 介面需穩定 Guid | Visual 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 共存遷移期的主流互操作場景。核心原則:
CoInitialize/Uninitialize、AddRef/Release、智慧指標完整原始碼 (四組專案) 請參考本文配套下載。適用於舊系統模組化遷移、.NET 與原生 C++ 混合開發、第三方 COM 組件整合等場景。