C# 将C字节[]编组到C++;带有DllImport的DLL 当我将C字节[]数组编排到C++时,我遇到了一些奇怪的行为。 当字节[]作为参数传递时,我得到C++中的预期数据。(见报告数据)

C# 将C字节[]编组到C++;带有DllImport的DLL 当我将C字节[]数组编排到C++时,我遇到了一些奇怪的行为。 当字节[]作为参数传递时,我得到C++中的预期数据。(见报告数据),c#,c++,marshalling,dllimport,C#,C++,Marshalling,Dllimport,当字节[]被包装在结构中时,我会得到奇怪的值。(参见ReportBuffer) 是什么导致了这种行为上的差异?在我需要将数据包装到更复杂的用例中时,是否有必要纠正这种差异 C#呼叫代码 公共结构缓冲区 { 公共int数据长度; 公共字节[]数据; 公共缓冲区(字节[]数据):this() { 数据=数据; DataLength=data.Length; } } 内部课程计划 { [DllImport(@“C:\Users\lawsm\source\repos\MarshallingTest\De

当字节[]被包装在结构中时,我会得到奇怪的值。(参见ReportBuffer)

是什么导致了这种行为上的差异?在我需要将数据包装到更复杂的用例中时,是否有必要纠正这种差异

C#呼叫代码

公共结构缓冲区
{
公共int数据长度;
公共字节[]数据;
公共缓冲区(字节[]数据):this()
{
数据=数据;
DataLength=data.Length;
}
}
内部课程计划
{
[DllImport(@“C:\Users\lawsm\source\repos\MarshallingTest\Debug\Test.dll”,CallingConvention=CallingConvention.Cdecl)]
私有静态外部无效报告缓冲区(缓冲区);
[DllImport(@“C:\Users\lawsm\source\repos\MarshallingTest\Debug\Test.dll”,CallingConvention=CallingConvention.Cdecl)]
私有静态外部无效报告数据(字节[]数据,整数数据计数);
私有静态void Main(字符串[]args)
{
字节[]数据=新字节[]{0,1,2,3,4,5};
缓冲区=新缓冲区(数据);
控制台写入线(“报告缓冲区”);
报告缓冲区(缓冲区);
Console.WriteLine(“\n\n报告数据”);
报表数据(数据,数据长度);
Console.ReadKey();
}
}
C++Dll代码

#包括
#包括
结构缓冲区
{
公众:
int数据长度;
uint8_t*数据;
};
外部“C”
{
_declspec(dllexport)void ReportBuffer(const Buffer和Buffer)
{
对于(int i=0;istd::cout我发现了一个解决方案,将byte[]数组更改为IntPtr,分配空间并复制数据

[StructLayout(LayoutKind.Sequential)]
公共结构缓冲区
{
公共int数据长度;
公共IntPtr数据;
公共缓冲区(字节[]数据):this()
{
Data=Marshal.AllocHGlobal(Data.Length);
封送处理副本(数据,0,数据,数据长度);
DataLength=data.Length;
}
}
[DllImport(“Buffer.dll”,CallingConvention=CallingConvention.Cdecl)]
私有静态外部无效报告缓冲区(缓冲区);
<> > C++代码保持不变:

struct缓冲区
{
公众:
int数据长度;
uint8_t*数据;
};
外部“C”
{
_declspec(dllexport)void ReportBuffer(const Buffer和Buffer)
{

std::cout没有问题。长度是前四个字节。由于微处理器的体系结构,长度字节的顺序被交换。有两个字节的段和两个字节的偏移量。您是否尝试用
[StructLayout(LayoutKind.Sequential)]
标记结构?[StructLayout(LayoutKind.Sequential)]在两种情况下,长度参数都不正确。下面的字节[]数据会被显示出来。在报告数据中,它正确地被作为0到5,在REPATH缓冲区中,它是通过1 0128,0,1错误声明,必须使用<代码> REF缓冲区< /C> >在C++侧获得缓冲区。注意,您仍然需要<代码>。[StructLayout(LayoutKind.Sequential)]
或者允许编译器在将来对您进行处理。在按照您的要求进行处理后,我的解决方案与您的解决方案有些相似。您说得很对,我将把它添加到awnser中。与将长度和数组作为单独参数传递的模式相比,这是非常糟糕的。您现在有一个以前没有的内存泄漏。@BenVoigt:哈哈,我错过了,他忘了释放内存。如果我没有将所有权转移到本机代码,我会锁定并取消绑定数组,但忘记取消绑定也同样糟糕。@Joshua:对。如果你将所有权转移到本机代码,你不能使用
封送。AllocHGlobal
,你必须使用分配函数matchi取消本机代码稍后执行的释放。
Report Buffer
1
0
128
0
1
0


Report Data
0
1
2
3
4
5