在 .NET 中,字符串(和 StringBuilder)是 16 位 Unicode 字符。我的猜测是你的本机函数处理 8 位 ASCII 字符。您需要告诉 Marshaller 在编组字符时如何转换字符。像这样更改您的 DllImport 属性:
[DllImport("myDLL.dll", CharSet=CharSet.Ansi)]
public static extern int ChannelName(int x, int y, [Out] StringBuilder z);
Updated
此外,您还应该在 StringBuilder 上指定 [Out] 属性,以便编组器仅在输出时进行编组,因为您在传入时不传递任何内容。
再次更新
[In,Out] 属性是多余的(这是默认值),但是将其放在那里可以明确表明您知道您需要 In 和 Out 复制。
[DllImport("myDLL.dll")]
private static extern int ChannelName(int x, int y, [In,Out] byte[] z);
public static int ChannelName(int x, int y, out string result)
{
byte[] z = new byte[100];
int ret = ChannelName(x, y, z);
result = Encoding.ASCII.GetString(z);
return ret;
}
再次更新
看起来(名字很糟糕)“y”参数是传入的 char * 缓冲区的长度,我的猜测是它返回写入缓冲区的字符数。如果是这种情况,我会以更自然的 C# 方式包装此调用:
[DllImport("myDLL.dll")]
private static extern int ChannelName(int x, int y, [In, Out] byte[] z);
public static string ChannelName(int x)
{
byte[] z = new byte[100];
int length = ChannelName(x, z.Length, z);
return Encoding.ASCII.GetString(z, 0, length);
}