亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

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

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

C#
繁花如伊 2023-09-16 19:58:45
這是一個非常奇怪的問題,我不知道是什么原因造成的......在 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 this摨玗????”。起初,我假設我在 C++/C# 代碼中犯了一個錯誤,因此,為了調試它,我決定返回“i”(在 C++ 方法中),以便我可以檢查循環走了for多遠,而且,出于某種原因,當我這樣做時,它突然起作用了。當我將 C++ 方法設置為返回整數(并將其放入 C# 中的變量中,如var i = GetPersonName...)時,由于某種原因,它突然將正確的字符串(這正是“源”所在)放入 StringBuilder 中。然后我進一步測試了它,讓它返回一個布爾值而不是整數,最后只是拍了return true一下 - 而且,再一次,它工作得很好。那么,只要返回類型不是 NOT void,它就有效嗎?為什么我會看到這種行為?而且,我怎樣才能做到即使該方法設置為“void”,它也能給出正確的輸出。
查看完整描述

1 回答

?
小唯快跑啊

TA貢獻1863條經驗 獲得超2個贊

您未能在 C++ 代碼中以 null 終止目標字符串。添加空終止符,您的代碼將會得到改進。


size_t len = wcslen(source);    

for (size_t i = 0; i < len; i++) {

    destination[i] = source[i];

}

destination[len] = 0;

另請注意,此代碼避免調用wcslen循環的每次迭代。當然,您同樣可以使用標準庫功能來執行 C 字符串復制,無需編寫另一個實現。


您仍然需要為字符串生成器對象設置適當的容量,否則您將面臨較長字符串緩沖區溢出的風險。而且看起來您可能存在 cdecl 與 stdcall 調用約定不匹配的情況。


查看完整回答
反對 回復 2023-09-16
  • 1 回答
  • 0 關注
  • 129 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號