我正在尝试将字符串从c ++传递到c#。
C++:
extern "C" __declspec(dllexport) void GetSurfaceName(wchar_t* o_name);
void GetSurfaceName(wchar_t* o_name)
{
swprintf(o_name, 20, L"Surface name");
}
C#:
[DllImport("SurfaceReader.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern void GetSurfaceName(StringBuilder o_name);
StringBuilder name = new StringBuilder(20);
GetSurfaceName(name);
但只传递第一个符号:name [0] =='S'。其他符号为空。你能告诉我这里有什么问题吗?
谢谢, 振亚
答案 0 :(得分:2)
您忘了告诉pinvoke marshaller该函数正在使用Unicode字符串。默认值为CharSet.Ansi,您需要显式使用CharSet.Unicode。修正:
[DllImport("SurfaceReader.dll",
CallingConvention = CallingConvention.Cdecl,
CharSet = CharSet.Unicode)]
private static extern void GetSurfaceName(StringBuilder o_name);
现在你会得到一个“S”,因为“S”的utf-16编码值看起来像一个带有一个字符的C字符串。
一般来说,请避免使用像“20”这样的幻数。只需添加一个参数,说明字符串缓冲区的长度。这样你就不会永远不会破坏GC堆。传递StringBuilder.Capacity。并为函数提供一个可以指示成功的返回值,这样您也不会忽略太小的缓冲区。
答案 1 :(得分:0)
我不确定,但不是使用StringBuilder,而是将C#char(wchar)数组传递给C ++,填充它然后在C#中使用此数组进行操作。