首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 與原生 C++ 互操作(四):封送、固定指標與 C++/CLI

     編輯:關於C語言

當 C++ 類型較複雜時,托管與非托管類型間的參數轉換(封送)成為核心挑戰。托管擴展雖自動處理基本類型與字串,但深入理解機制對解決疑難雜症至關重要。

固定指標與 PtrToStringChars

托管物件位於 GC 堆,垃圾回收器可能移動物件導致原生指標失效。`__pin` 關鍵字可固定物件位置。框架提供 `PtrToStringChars` 取得固定的原生字元指標:

// vcclr.h 中定義
inline const System::Char* PtrToStringChars(const System::String* s) {
    const System::Byte* bp = reinterpret_cast<const System::Byte*>(s);
    if (bp != 0) {
        unsigned offset = System::Runtime::CompilerServices::RuntimeHelpers::OffsetToStringData;
        bp += offset;
    }
    return reinterpret_cast<const System::Char*>(bp);
}

互操作進階主題

  • 陣列、引用、結構、回調 的封送處理
  • StructLayout 控制記憶體佈局
  • Boxing/Unboxing 與 `__value` 類型
  • 異常處理與委托回調

C++/CLI:新一代托管 C++

Visual Studio 2005 引入 C++/CLI(Managed Extensions 2.0),語法與語義全面升級:

  • 使用 `^` (hat) 替代 `*` 表示托管控制代碼:`String^ s = gcnew String();`
  • `gcnew` 明確在托管堆分配,避免與原生 `new` 衝突
  • 設計目標:突顯而非模糊 托管/非托管差異

實踐建議

  1. 先確定調用方向:托管→非托管(P/Invoke 或包裝器)或 非托管→托管(Managed Extensions/C++/CLI)。
  2. 優先使用包裝器封裝 C++ 類,避免直接 P/Invoke 成員函數(調用約定、名稱修飾極易出錯)。
  3. 善用 `PtrToStringChars`、`pin_ptr` 等工具處理字串與陣列固定。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved