1. 程式人生 > >C語NET調用 C++ dll 函數 時傳遞字符串 需要註意的問題

C語NET調用 C++ dll 函數 時傳遞字符串 需要註意的問題

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 函數 時傳遞字符串 需要註意的問題