C++ <--> C# 修改编组的字节数组

Posted

技术标签:

【中文标题】C++ <--> C# 修改编组的字节数组【英文标题】:C++ <--> C# modify a marshalled array of bytes 【发布时间】:2011-08-10 13:28:45 【问题描述】:

我有一个非托管 C++ 函数,它在 DLL 中调用托管 C# 方法。 C# 方法的目的是获取一个字节数组(由 C++ 调用者分配),填充该数组并返回它。我可以将数组输入到 C# 方法中,但是当它们返回到 C++ 函数时,填充的数据会丢失。现在,这是我调试进程的测试代码:

C# DLL 方法:

// Take an array of bytes and modify it
public ushort GetBytesFromBlaster([MarshalAs(UnmanagedType.LPArray)] byte[] dataBytes)

    dataBytes[0] = (byte)'a';
    dataBytes[1] = (byte)'b';
    dataBytes[2] = (byte)'c';
    return 3;

调用 DLL 的 C++ 函数:

// bytes[] has been already allocated by its caller
short int SimGetBytesP2P(unsigned char bytes[])

    unsigned short int numBytes = 0;
    bytes[0] = 'x';
    bytes[1] = 'y';
    bytes[2] = 'z';
    // bytes[] are 'x', 'y', 'z' here
    guiPtr->GetBytesFromBlaster(bytes, &numBytes);
    // bytes[] SHOULD be 'a', 'b', 'c' here, but they are still 'x', 'y', 'z'
    return(numBytes);

我相信这与 C# 将 C++ 指针转换为新的托管数组有关,但修改了原始数组。我使用“ref”修饰符等尝试了几种变体,但没有运气。此外,这些数据不是以 null 结尾的字符串;日期字节是原始的 1 字节值,不是以 null 结尾的。

任何人都可以对此有所了解吗?谢谢!

斯图尔特

【问题讨论】:

【参考方案1】:

您可以自己进行编组。让 C# 函数按 IntPtr 类型的值接受参数。还有一个表示数组长度的第二个参数。不需要或不需要特殊的编组属性。

然后,使用 Marshal.Copy 并将数组从非托管指针复制到您分配的托管 byte[] 数组。做你的事,然后当你完成后,使用 Marshal.Copy 将它复制回 C++ 非托管数组。

这些特定的重载应该可以帮助您入门:

http://msdn.microsoft.com/en-us/library/ms146625.aspx http://msdn.microsoft.com/en-us/library/ms146631.aspx

例如:

public ushort GetBytesFromBlaster(IntPtr dataBytes, int arraySize)

    byte[] managed = new byte[arraySize];
    Marshal.Copy(dataBytes, managed, 0, arraySize);
    managed[0] = (byte)'a';
    managed[1] = (byte)'b';
    managed[2] = (byte)'c';
    Marshal.Copy(managed, 0, dataBytes, arraySize);
    return 3;

或者,如果默认编组器没有按照您的需要执行,您可以按照http://msdn.microsoft.com/en-us/library/w22x2hw6.aspx 中的描述实现自定义编组器。但这看起来需要更多的工作。

【讨论】:

【参考方案2】:

我相信你只需要添加一个SizeConst属性:

public ushort GetBytesFromBlaster(
    [MarshalAs(UnmanagedType.LPArray, SizeConst=3)] 
    byte[] dataBytes
)

而默认编组器应该为您完成其余的工作。

【讨论】:

以上是关于C++ <--> C# 修改编组的字节数组的主要内容,如果未能解决你的问题,请参考以下文章

C++ 到 C# 回调结构编组

如何在 C# 中编组数据类型 unsigned char**?

如何编组多字节字符集 C#

我如何编组列表<int>?

C 到 C# 数组编组中的矛盾行为

将引用类型从 C++ 编组到 C#