這是一個非常奇怪的問題,我不知道是什么原因造成的......在 C++ DLL 中,我有一個方法,出于演示目的,該方法非常簡單,只需傳入兩個字符指針,一個是源,一個是目標(biāo)。很簡單,運(yùn)行該方法時發(fā)生的所有事情就是將所有字符從一個字符串復(fù)制到另一個字符串中。這是方法: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. 當(dāng)我調(diào)用它時,我傳入 StringBuilder 作為目標(biāo),然后傳入Unicode字符串作為源(如果我只傳入 ASCII 字符串,則不會發(fā)生此問題)。只是為了演示我在其中添加了兩個漢字(這個)。[DllImport("CPPDLLImport.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]static extern void GetPersonName(StringBuilder output, string str);... var str = new StringBuilder(); GetPersonName(str, "Hi這個");而且,它絕對沒有將我期望的內(nèi)容放入 StringBuilder - 它放入:“Hi this摨玗????”。起初,我假設(shè)我在 C++/C# 代碼中犯了一個錯誤,因此,為了調(diào)試它,我決定返回“i”(在 C++ 方法中),以便我可以檢查循環(huán)走了for多遠(yuǎn),而且,出于某種原因,當(dāng)我這樣做時,它突然起作用了。當(dāng)我將 C++ 方法設(shè)置為返回整數(shù)(并將其放入 C# 中的變量中,如var i = GetPersonName...)時,由于某種原因,它突然將正確的字符串(這正是“源”所在)放入 StringBuilder 中。然后我進(jìn)一步測試了它,讓它返回一個布爾值而不是整數(shù),最后只是拍了return true一下 - 而且,再一次,它工作得很好。那么,只要返回類型不是 NOT void,它就有效嗎?為什么我會看到這種行為?而且,我怎樣才能做到即使該方法設(shè)置為“void”,它也能給出正確的輸出。
1 回答

小唯快跑啊
TA貢獻(xiàn)1863條經(jīng)驗(yàn) 獲得超2個贊
您未能在 C++ 代碼中以 null 終止目標(biāo)字符串。添加空終止符,您的代碼將會得到改進(jìn)。
size_t len = wcslen(source);
for (size_t i = 0; i < len; i++) {
destination[i] = source[i];
}
destination[len] = 0;
另請注意,此代碼避免調(diào)用wcslen循環(huán)的每次迭代。當(dāng)然,您同樣可以使用標(biāo)準(zhǔn)庫功能來執(zhí)行 C 字符串復(fù)制,無需編寫另一個實(shí)現(xiàn)。
您仍然需要為字符串生成器對象設(shè)置適當(dāng)?shù)娜萘?,否則您將面臨較長字符串緩沖區(qū)溢出的風(fēng)險。而且看起來您可能存在 cdecl 與 stdcall 調(diào)用約定不匹配的情況。
- 1 回答
- 0 關(guān)注
- 146 瀏覽
添加回答
舉報
0/150
提交
取消