C# PInvoke out字符串声明

9
在C#的PInvoke中,我如何传递字符串缓冲区以便C DLL填充并返回?PInvoke声明应该是什么?
C函数声明为:
int GetData(char* data, int buflength);

在C#中,我已经将其声明为:
[DllImport(DllName)]
static extern Int32 GetData([MarshalAs(UnmanagedType.LPStr)]StringBuilder receiveddata, Int32 buflen);

这样传递StringBuilder变量是正确的吗?

int bufferLength = 32;
StringBuilder data = new StringBuilder(bufferLength);
int result = GetData(data, bufferLength);

我想知道这是否正确?

谢谢


2
只要它能工作,那就是正确的。没有明显的原因说明它不能工作。 - Hans Passant
2个回答

9

我相信这是正确的。

[DllImport(DllName)]
static extern int GetData(StringBuilder data, int length);

这个被称为:

StringBuilder data = new StringBuilder(32);
GetData(data, data.Capacity);

我曾经想要更好地控制函数返回的字节,我是这样做的:

[DllImport(DllName)]
private unsafe static bool GetData(byte* data, int length);

使用方法如下:

byte[] bytes = new byte[length];

fixed(byte* ptr = bytes)
{
  bool success = Library.GetData(ptr, length);

  if (!success)
    Library.GetError();

  return Encoding.UTF8.GetString(bytes);
}

4

我认为在这里使用MarshalAs属性是不必要的。StringBuilder是char*输出的正确选择。

我猜在这里处理字符串时添加CharSet属性会很好。

像这样:

[DllImport(DllName, CharSet=CharSet.Auto)]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接