C語NET調用 C++ dll 函數 時傳遞字符串 需要註意的問題
阿新 • • 發佈:2017-06-10
sed class .net tle new pen eight 一個 問題
1:C# 調用 返回 字符串 C++ native dll 函數 的註意事項:
a:C++ DLL的返回值,安全的做法是分配一個全局 char 數組,把要返回的 char * 復制到這個 char 數組中,
1 char buff[255]; 2 3 const char* __stdcall ReturnString() 4 { 5 strcpy(buff,"xxxxxxxxxxxxxxx"); 6 return buff; 7 }
b:C# 收到 字符串後,需要 Marshal
1 [DllImport("VC.dll", EntryPoint = "ReturnString", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Winapi)] 2 public static extern IntPtr ReturnString();
調用VCDLL的代碼...
1 IntPtr intPtr = ReturnString(); 2 3 string str = Marshal.PtrToStringAnsi(intPtr);View Code
因為 C++ 返回的是 char* ,是個指針,所以c# 要用 IntPtr 來接回。
Marshal.PtrToStringAnsi MSDN上的解釋:將非托管 ANSI 字符串中第一個空值(空值就是\0)之前的所有字符復制到托管 String。將每個 ANSI 字符擴展為 Unicode 字符。
2:用參數傳遞,即C++dll 函數的參數 定義為 char*,而C#傳遞 StringBuilder 給 c++
a:c# 創建一個 StringBuilder,並初始化 capacity後傳給C++
[DllImport("VC.dll", EntryPoint = "ProcessString", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Winapi)] public static extern void ProcessString(StringBuilder str); //調用VCDLL的代碼...StringBuilder str = new StringBuilder(255); //255 是 capacity ProcessString(str); MessageBox.Show(str); //不需要Marshal,直接使用
b:C++ DLL函數
const char* __stdcall ProcessString(char* str) { //str 是 c# 創建的 StringBuilder,長度是255 strcpy(str,"xxxxxxxxxxxxxxx"); return buff; } 其他的請
參考msdn中的c++與c#的類型轉換 對應關系如下:
C++ ---- C#
傳入的char* ----string
傳出的char* ---- StringBuilder(預分配空間)
short ----short char ---- byte char[n] ---- fixed byte[n]
結構指針 ----結構指針
函數指針 ---- 委托
C語NET調用 C++ dll 函數 時傳遞字符串 需要註意的問題