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

标签 c# c++ interop pinvoke marshalling

我有一个非托管 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 结尾。

有人可以解释一下吗?谢谢!

斯图尔特

最佳答案

您可以自己进行编码。让 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 中所述。如果默认的没有做你需要的事情。但这看起来需要更多工作。

关于c# - C++ <--> C# 修改字节编码数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7011567/

相关文章:

c# - 如何阻止用户打开 Internet Explorer 或 Firefox 等新进程?

c# - 在 C# 中,您能说出哪个是将 INT 数字提升到任何所需程度的标准函数吗?

c# - 如何与 LINQ where 中省略的空间进行比较?

C++ 静态变量产生 fatal error LNK1120 : 1 unresolved externals in Visual Studio

c - Fortran-C 桥接中的字符串数组使用 iso_c_binding

c# - ASP.NET MVC 表单验证每次都失败

c++ - Linux 上没有控制台应用程序

c++ - 来自 bitset<n> 的有符号整数

c# - 在 C# 中的段落范围内添加制表位

c# - Internet Explorer 工具栏 Tab 键