需將原生 C++ SDK 包裝為 .NET 組件供 C# 呼叫。C++/CLI 雖語法醜陋,但比 P/Invoke 互操作簡潔得多,特別適合「原生 → 托管」薄包裝層。
| 項目 | C++/CLI 語法 | 說明 |
|---|---|---|
| 參考型別變數 | String^ var, array<int>^ arr | ^ 為追蹤控制碼 (handle),對應 .NET 參考型別 |
| 值型別 | int val | 無 ^,直接存儲值 |
| 枚舉定義 | public enum class Flag : unsigned int { A=1, B=2 }; | 加 class/struct 才是 .NET 枚舉,可指定底層型別與 [Flags] |
| 原生字串 → .NET | String^ s = gcnew String(native_char_ptr); | gcnew 分配於受控堆積 |
| .NET 字串 → 原生 | pin_ptr<const wchar_t> p = PtrToStringChars(str); | pin_ptr 釘住記憶體防 GC 移動,轉 wchar_t* |
| 空指標/控制碼 | nullptr | 取代 NULL/0,避免裝箱歧義 |
ref 參數 | void foo(String^% refStr); | % 對應 C# ref |
out 參數 | void foo([Out] String^% outStr); | 需 [OutAttribute] |
| 陣列建立 | array<int>^ arr = gcnew array<int>(100); | 用圓括號非方括號,長度在建構函式傳遞 |
禁用 const | 托管型別成員不可用 const/volatile | 編譯報錯時移除 |
DllMain 注意 | 勿在 DllMain 執行托管代碼,極易死結 | 可用 #pragma managed(push, off) 區段隔離 |
!ClassName() (Finalizer) 和 ~ClassName() (Dispose) 中釋放,實作 IDisposable。ArgumentException, IOException 等)。/clr (非 /clr:pure,需混合原生代碼)。C++/CLI 是連接原生與托管世界的強力膠水。掌握上述核心語法與資源管理模式,即可高效產出高品質 .NET 互操作組件。