簡體   English   中英

Unicode字符串不適用於P / Invoke中的void

[英]Unicode string not working with void in P/Invoke

這是一個非常奇怪的問題,我不知道是什么原因引起的。

在C ++ DLL中,我有一個方法,出於演示目的,此方法非常簡單,您只需傳入兩個字符指針,一個是源字符,一個是目標字符。 簡而言之,運行該方法時發生的所有事情就是它將所有字符從一個字符串復制到另一個字符串。

這是方法:

extern "C" __declspec(dllexport) void GetPersonName(wchar_t* destination, wchar_t* source) {
    unsigned int i = 0;
    for (i = 0; i < wcslen(source); i++) {
        destination[i] = source[i];
    }
}

而且,在C#中,我使用DllImport調用此方法。 調用它時,我傳入StringBuilder作為目標,然后僅傳入Unicode字符串作為源(如果我只是傳入ASCII字符串,則不會發生此問題)。 為了演示,我在其中添加了兩個漢字。

[DllImport("CPPDLLImport.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
static extern void GetPersonName(StringBuilder output, string str);

...

 var str = new StringBuilder();
 GetPersonName(str, "Hi這個");

而且,它絕對不會將我期望的內容放入StringBuilder中,而是將其放入:“ Hi這個摨玗öö”。

首先,我假設我在C ++ / C#代碼中犯了一個錯誤,因此,為了對其進行調試,我決定返回“ i”(在C ++方法中),以便可以檢查for循環的距離for走了,由於某種原因,當我這樣做時,它突然起作用了。

當我設置C ++方法以返回整數(並將其放入C#的變量中,例如var i = GetPersonName... )時,由於某種原因,它突然放入了正確的字符串(這就是“源”的含義) )放入StringBuilder。

然后,我對其進行了進一步的測試,使它返回一個布爾值而不是整數,並在最后將其返回值設置return true ,並且再次運行良好。

那么,只要返回類型不是void ,它就起作用嗎?

為什么我會看到這種行為? 而且,我如何才能做到,即使將方法設置為“ void”,也能提供正確的輸出。

您無法以空值終止在C ++代碼中的目標字符串。 添加該空終止符,您的代碼將得到改善。

size_t len = wcslen(source);    
for (size_t i = 0; i < len; i++) {
    destination[i] = source[i];
}
destination[len] = 0;

還要注意,此代碼避免在循環的每次迭代中調用wcslen 當然,您同樣可以很好地使用標准庫功能來執行C字符串復制,而無需為此編寫其他實現。

您仍然需要為字符串構建器對象設置適當的容量,否則冒較長字符串可能導致緩沖區溢出的風險。 而且看起來您可能有cdecl vs stdcall調用約定不匹配的情況。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM