【问题标题】:Getting byte array from C into C#将字节数组从 C 获取到 C#
【发布时间】:2016-08-20 14:46:11
【问题描述】:

我需要从 C# 调用以下 C 函数:

__declspec(dllexport) int receive_message(char* ret_buf, int buffer_size);

我在 C# 方面声明了以下内容:

[DllImport("MyCLibrary", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto, EntryPoint = "receive_message")]
public static extern int ReceiveMessage([MarshalAs(UnmanagedType.LPStr)]StringBuilder retBuf, int bufferSize);

我这样调用函数:

StringBuilder sb = new StringBuilder();
int len = ReceiveMessage(sb, 512);

这适用于我收到“字符串”消息的初始测试。但是,现在我想接收打包的消息(字符/字节数组)。问题是字符/字节数组将有 0 并将终止字符串,因此我不会取回整个消息。有什么想法可以重构以获取字节数组吗?

【问题讨论】:

  • 使用 Marshal.Copy(IntPtr source, byte[] destination, int startIndex, int length)。
  • @jdweng,我没有关注。我需要在我的 C# 中更改我的 extern 声明吗?
  • 你在吹嘘 bufferSize 参数,StringBuilder 的容量是 0。这可能导致的堆损坏可能非常令人不快。如果它实际上不是一个字符串,那么您必须 将第一个参数声明为 byte[]。同样,将其 Length 属性作为第二个参数传递。
  • 我确实注意到我的记忆在慢慢增长……也许这就是原因。我想我找到了 jdweng 推荐的 Marshall.Copy。确认后我会发布完整答案。

标签: c# c marshalling unmanaged


【解决方案1】:

在 jdweng 的帮助下,我将声明更改为:

[DllImport("MyCLibrary", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto, EntryPoint = "receive_message")]
public static extern int ReceiveMessage(IntPtr retBuf, int bufferSize);

而且,我在 C# 端分配和释放内存以及编组数据。

IntPtr pnt = Marshall.AllocHGlobal(512);
try
{
   int len = ReceiveMessage(pnt, 512);
   ...
   byte[] bytes = new byte[len];
   Marshal.Copy(pnt, bytes, 0, len);
   ...
}
finally
{
   Marshal.FreeHGlobal(pnt);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多