.NET 設計初期即重視與既有代碼整合,互操作雖可行,但存在三大開銷:資料封送處理、大量資料跨邊界傳輸效能、開發維護複雜度。若非必要,優先考慮「完全重寫」策略(參見第 5 章)。必須互操作時,需權衡三種策略優劣。
資料封送優化原則
- 偏好「笨重」API:單次呼叫傳遞大量資料,減少跨邊界次數(類比網路服務的 chunky vs chatty);
- 優先使用 blittable 型別:託管與非託管記憶體配置相同,可直接記憶體複製,無需轉換。包含基本整數型別、單維陣列、配合
StructLayout(LayoutKind.Sequential) 的結構;
- 善用
InAttribute/OutAttribute 控制雙向/單向複製;
- 字串預設用 BSTR 封送,效能最差,可用
MarshalAs(UnmanagedType.LPWStr) 指定 wchar* 格式。
三大互操作策略比較
1. COM 互操作
- 優點:使用現有 COM 元件最簡單;
- 缺點:效能最差(含 COM 執行期開銷、RCW/CCW 封送、生命週期管理複雜);
- 建議:除非 COM 元件價值極高,否則避免。若必須用,讓 CLR 管理生命週期(接受效能損失),勿手動呼叫
ReleaseCOMObject。
2. P/Invoke(平台呼叫)
- 優點:繞過 COM 層,直接呼叫 Win32 API,效能較好;
- 缺點:需手寫每個方法簽章(含修飾名),非物件導向,維護負擔重;
- 適用:少量 C 風格 Win32 API 呼叫。
3. Managed C++(/clr 編譯選項)
- 優點:可直接混合託管/非託管代碼,無 thunking 開銷,對封送邏輯有完全控制權;
- 缺點:需手寫包裝類別(代碼重複、易錯)、自行管理非託管資源釋放、C++ 模板/例外與 C# 不兼容、產生非驗證安全代碼(需完全信任);
- 適用:大量既有 C++ 代碼庫(非 COM)整合的最佳選擇。
決策建議
- 優先評估「完全重寫」可行性;
- 既有 COM 元件 → COM 互操作;
- 既有 C++ 代碼 → Managed C++ (/clr);
- 少量 Win32 API → P/Invoke;
- 選擇開發成本最低、維護性最好的策略。