2011-05-20 56 views
1

我有這個C++函數調用非託管代碼,馬歇爾的char **字符串問題從託管代碼

bool MyClass::my_function(int num, TCHAR** filepath) 

我已經暴露出功能

extern "C" 
    { 
     __declspec(dllexport) bool MyFunction(int num, char* filepath[]) 
     { 
      OutputDebugStringA("--MyFunction--"); 
      TCHAR **w_filepath = (TCHAR **)calloc(num, 2* sizeof(TCHAR **)); 
      for(int i = 0; i < num; i++) 
      { 
      OutputDebugStringA(filepath[i]); 
      int len = strlen(filepath[i]) + 1; 
      w_filepath[i] = (TCHAR *)calloc (1, len); 
      ctow(w_filepath[i], filepath[i]); // converts char to WCHAR 
      } 

      bool ret = MyClass.my_function(num, w_filepath); 
      OutputDebugStringA("End -- MyFunction --"); 
      free(w_filepath); 
      return ret; 
     } 
    } 

我有C#包裝器

[DllImport("MyDll.dll")] 
    public static extern bool MyFunction(int num, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPTStr)] string[] filepath); 

在C#,我調用myFunction的作爲

string [] filepath = { "D:\\samplefile\\abc.txt", "D:\\samplefile\\def.txt"} 
    MyFunction(2, filepath) 

在C++函數中,它只獲取文件路徑的第一個字符。 例如,來自上述呼叫,如果我使用

OutputDebugStringA 

它打印僅d爲第一和第二打印在C++代碼。

如果我從C#包裝 刪除

[MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPTStr)] 

我會訪問衝突錯誤

w_filepath[i] = (TCHAR *)calloc (1, len) 

的第二個文件。

請幫幫我。

+0

C#將字符串表示爲unicode。您期望通過char *。 – Nick 2011-05-20 08:18:19

+0

在C++中,不要使用char。改用TCHAR。這樣,你可以應付unicode。 – 2011-05-20 09:39:55

回答

1

1)w_filepath[i] = (TCHAR *)calloc (1, len); - 釋放calloc需要字節大小,所以它應該是w_filepath[i] = (wchar_t *)calloc (1, len*sizeof(wchar_t));

2)從C#的數據來作爲爲wchar_t *,所以你不需要轉換套路可言,而應該改變函數聲明

__declspec(dllexport) bool MyFunction(int num, wchar_t* filepath[])