为了完成这项工作,我已经苦苦挣扎了一天。它在 Windows 上运行良好,但在带有单声道的 Linux 上运行不佳。
我正在努力实现的目标
C# 包装器
[DllImport("MyLib.dll", CharSet = CharSet.Unicode)]
public static extern int MyFunction(StringBuilder str);
StringBuilder myString = new StringBuilder(255);
var ret = MyFunction(myString);
Console.WriteLine("Result: {0}",myString.ToString());
C++ 共享库(.dll 或 .so)
WRAPPER_API int _stdcall MyFunction(wchar_t* str)
{
wcscpy(str,L"this is a test");
return 0;
}
结果
window :
Result: this is a test
Linux:
Result: t
在单声道上,返回的字符串仅包含字符串的第一个字符。 我尝试使用 ANSI 字符串将 wchar_t* 更改为 char* 并将 wcscpy 更改为 strcpy 并且有效。
我的测试环境
Linux Ubuntu 32 bits 12.04 LTS / Mono 4.3.2
Windows 7 64 bits .Net 4.5
其他问题和引用
How do I marshal wchar_t* from C++ to C# as an out parameter or return value?
http://www.mono-project.com/docs/advanced/pinvoke/#passing-caller-modifiable-strings
编辑: 感谢@Xanatos 的回答,我能够使用 u16string 解决我的问题(我有 g++ 4.8.4 并启用 c++11 标准):
WRAPPER_API int _stdcall MyFunction(chart16_t* str)
{
u16string someString(u"some unicode string");
someString.copy(str, someString.length());
return 0;
}
最佳答案
wchar_t
有问题在 Linux 中:sizeof(wchar_t) == 4
(在 Windows 上 sizeof(wchar_t) == 2
)。遗憾的是,Linux/其他 Unix(es) 上的 Mono 没有做任何事情来解决它,并考虑 sizeof(wchar_t) == 2
无处不在(例如参见 http://mono-list.ximian.narkive.com/QzgsoSlk/support-for-marshalling-of-c-string-to-unmanaged-wchar-t-on-linux 和 http://mono.1490590.n4.nabble.com/What-is-Correct-way-to-marshal-wchar-t-td1506090.html 。)
对此没有简单的解决方案。如果您使用较新的 C++,您可以使用 char16_t
及其功能 std::char_traits<char16_t>::*
.
关于C# mono - 传递 stringbuilder 以填充 C++ 中的 unicode 内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35982310/