MFC (C++) 專案需呼叫 C# 組件,標準做法:將 MFC 專案設為 /clr (Common Language Runtime 支援),透過 #using 導入 .NET 組件,並在呼叫代碼前加 #pragma managed 進入 managed 區段。本文完整記錄 VS 專案屬性設定、代碼導入、混合模式編程三大步驟。
Common Language Runtime Support (/clr)Use MFC in a Shared DLLProgram Database (/Zi) (非 /ZI)Multi-threaded Debug DLL (/MDd) 或 Multi-threaded DLL (/MD)關鍵:/clr 必須搭配 /MD 或 /MDd,否則連結錯誤。
// 標頭檔或 cpp 頂部
#using
#using "YourCSharpAssembly.dll" // 你的 C# DLL 路徑
using namespace System;
using namespace YourCSharpNamespace; // C# 類別所在命名空間
#using 會讀取組件中繼資料,產生 C++ 可呼叫的包裝類別。
void YourMfcFunction()
{
// Unmanaged 代碼區...
#pragma managed(push, on) // 進入 Managed 區段
{
// 呼叫 C# 類別
YourCSharpNamespace.YourClass^ obj = gcnew YourCSharpNamespace.YourClass();
obj->YourMethod();
}
#pragma managed(pop) // 返回 Unmanaged 區段
// 繼續 Unmanaged 代碼...
}
#pragma managed(push, on):啟用 managed 編譯,允許使用 gcnew、^ 等 C++/CLI 語法#pragma managed(pop):恢復 unmanaged 編譯#pragma managed 放在函數開頭// MFC Dialog 類別
void CMfcDlg::OnBnClickedCallCSharp()
{
#pragma managed
{
try
{
MyCSharpLib.Calculator^ calc = gcnew MyCSharpLib.Calculator();
int result = calc->Add(10, 20);
CString msg; msg.Format(_T("C# 回傳: %d"), result);
AfxMessageBox(msg);
}
catch (System::Exception^ ex)
{
CString err; err.Format(_T("C# 例外: %s"), gcnew CString(ex->Message));
AfxMessageBox(err);
}
}
}
| 問題 | 原因 | 解決 | |
|---|---|---|---|
| 連結錯誤 LNK2028 | Runtime Library 不匹配 | 統一專案與所有靜態庫為 /MD 或 /MDd | |
| 載入 DLL 失敗 | C# DLL 依賴未複製到輸出目錄 | 設定 C# 專案「複製到輸出目錄」或手動複製 | |
| 呼叫例外 System.IO.FileNotFoundException | 組件解析路徑錯誤 | 在 App.config 加 <probing privatePath="..\ManagedLibs\" /> | |
| Debug 斷點不生效 | /Zi vs /ZI、PDB 不匹配 | 確保 C++ 專案用 /Zi,C# 專案產生 PDB (Debug 模式) | |
| 記憶體洩漏 | 未正確釋放 COM/CLR 物件 | 使用 gcroot<T>、auto_gcroot 或手動 delete (針對 native 指標) |
| 方案 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|
| /clr + #using (本文) | 強型別、IntelliSense、例外互通、效能佳 | 需編譯為 mixed mode、部署複雜度稍高 | 核心邏輯深度整合 |
| COM Interop (CCW) | 純 Unmanaged C++、無 /clr | 需註冊、介面定義繁瑣、效能較差 | 舊專案無法改 /clr |
| C++/CLI Wrapper DLL | 隔離 mixed mode、提供純 C 介面給 MFC | 多一層專案 | 大型團隊、架構分層 |
| Named Pipe / TCP / gRPC | 進程隔離、跨語言、可獨立部署 | 序列化開銷、延遲、複雜度高 | 微服務、跨機器 |