在 .NET 開發環境中,有時我們需要呼叫高效能的非受控程式碼(如 C++ 或組合語言),同時又希望保留 .NET 組件的易用性。本文將詳細介紹如何使用 Visual Studio 2008,透過組件連結器 Al.exe,將 Managed Code(C#)與 Unmanaged Code(C++/ASM)封裝在同一個 DLL 中,打造一個同時支援 .NET 與原生 C/C++ 呼叫的「Perfect DLL」。
.NET 組件可由多個模組(.netmodule)組成。我們將 C# 程式碼編譯為模組,而非獨立組件;再將 C++ 專案編譯為 DLL 時,將該 .netmodule 納入連結輸入,最終產出單一混合模式 DLL。
在 Visual Studio 中建立一個名為 asmproject 的 C++ Win32 DLL 專案。
在 asmproject.cpp 中實作一個簡易的 add 函式,使用內嵌組合語言進行整數加法:
extern "C" __declspec(dllexport) int add(int a, int b)
{
int c;
__asm
{
mov eax, a;
add eax, b;
mov c, eax;
}
return c;
}
新增一個 C# Class Library 專案 asmlibrary,定義一個靜態類別透過 P/Invoke 呼叫上述原生函式:
public static class asmlibrary
{
[DllImport("asmlibrary.dll")]
public static extern int add(int a, int b);
}
注意: DllImport 引用的正是我們即將產出的混合模式 DLL 本身。
這是關鍵步驟。用文字編輯器開啟 asmlibrary.csproj,找到 <OutputType> 節點,將其值改為 Module 並儲存。回到 VS 建置專案,輸出目錄將產生 asmlibrary.netmodule 檔案。
開啟 asmproject 的屬性頁:
asmlibrary.netmodule。asmlibrary.dll。重新建置 C++ 專案,即可獲得名為 asmlibrary.dll 的混合模式組件。
建立一個 C# Windows Application 專案,加入對 asmlibrary.dll 的參考,即可直接呼叫 asmlibrary.add()。使用 ILDASM 或 Dependency Walker 等工具檢視該 DLL,可見其同時包含 Managed 中繼資料與 Unmanaged 匯出函式,確認混合模式建立成功。
透過「C# 編譯為 .netmodule → C++ 連結 .netmodule 產出 DLL」的流程,我們成功將 Managed 與 Unmanaged 程式碼整合在單一檔案中。此技術適用於效能關鍵路徑需使用組合語言或既有 C++ 庫的情境,簡化部署並保持介面一致性。