1

我正在尝试将字符串从 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'。其他符号为空。你能告诉我这里有什么问题吗?

谢谢,振亚

4

2 回答 2

2

您忘记告诉 pinvoke 编组器该函数正在使用 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。并为函数提供一个可以指示成功的返回值,这样您也不会忽略太小的缓冲区。

于 2013-05-15T17:14:57.020 回答
0

我不确定,但不是使用 StringBuilder,而是从 C# char (wchar) 数组传递到 C++,填充它,然后在 C# 中使用这个数组进行操作。

于 2013-05-15T17:07:33.700 回答