C# mono - 传递 stringbuilder 以填充 C++ 中的 unicode 内容

C# mono - passing stringbuilder to fill with unicode content in C++

为了完成这项工作,我已经苦苦挣扎了一天。它 在 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;
}

结果

Windows:

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;
}

Linux 中的 wchar_t 存在问题:sizeof(wchar_t) == 4(在 Windows sizeof(wchar_t) == 2 上)。可悲的是 Linux/other Unix(es) 上的 Mono 没有做任何事情来解决它,并且到处都考虑 sizeof(wchar_t) == 2 (例如参见 [​​=16=] 。)

对此没有简单的解决方案。如果您使用较新的 C++,您可以使用 char16_t 及其函数 std::char_traits<char16_t>::*.