C#嵌套结构封送-对象

C#嵌套结构封送-对象,c#,nested,structure,marshalling,C#,Nested,Structure,Marshalling,我有以下嵌套结构 [StructLayout(LayoutKind.Sequential, Pack = 1)] struct ERROR_ITEM { byte ErrorID; }; [StructLayout(LayoutKind.Sequential, Pack = 1)] struct ERROR_DATA { [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeC

我有以下嵌套结构

[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct ERROR_ITEM
{
    byte ErrorID;
};

[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct ERROR_DATA
{
    [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = 10)]
    ERROR_ITEM[] ErrorItem;

};

[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct VCP_DATA
{
    [MarshalAs(UnmanagedType.Struct)]
    ERROR_DATA ErrorData;
};
我需要将一个字节数组复制到这个结构中,所以我尝试了以下方法

vcpBuffer = new VCP_DATA();       
GCHandle handle = GCHandle.Alloc(vcpBuffer, GCHandleType.Pinned);
try
{
    IntPtr pBuffer = handle.AddrOfPinnedObject();
    Marshal.Copy(bytarray, 0, pBuffer, length);
}
finally
{
    if (handle.IsAllocated)
        handle.Free();
}
但是GCHandle.Alloc()返回mscorlib.dll中发生的错误“System.Argument.Execution类型的未处理异常”。
附加信息:对象包含非基本数据或不可blittable数据。

首先,错误项[]是一个托管数组,因此它不是一个可blittable结构。它只是一个托管引用。引用指向的内存有一个syncblock、方法表指针和一个位于实际元素前面的长度说明符

但是,使用'fixed'()不会有任何帮助(请检查我的情况)。要克服此错误,由于
error\u ITEM
[]具有固定长度,只需将数组替换为16个
error\u ITEM
字段。您仍然可以对第一个
错误项
错误项*
)的地址使用数组语法来访问后续元素

或者,只需计算所有16个元素的大小,但只包括第一个元素作为字段,然后在
StructLayout
属性上为
ERROR\u DATA
指定
size
参数,使其足够大,可以容纳所有元素


此外,当实际的编译器对嵌套的东西非常满意时,Resharper有时会抱怨它。但这是因为它是一个数组。根据我的经验,即使是一个固定的不安全的embdeded数组也会让C#认为它不适合使用。

谢谢你的建议。我相信他们会奏效,但我找到了另一种方法来做我需要的事情。vcpBuffer=新的VCP_数据();GCHandle handle=GCHandle.Alloc(bytearray,GCHandleType.pinted);请尝试{IntPtr pBuffer=handle.AddrOfPinnedObject();vcpuffer=(VCP_数据)Marshal.PtrToStructure(pBuffer,typeof(VCP_数据));}最后{if(handle.IsAllocated)handle.Free();}@Hassan-您应该给出答案并接受它!这样做是合法的,可以改善网站。
vcpBuffer = new VCP_DATA();
GCHandle handle = GCHandle.Alloc(bytearray, GCHandleType.Pinned); 
try 
{ 
    IntPtr pBuffer = handle.AddrOfPinnedObject(); 
    vcpBuffer = (VCP_DATA)Marshal.PtrToStructure(pBuffer, typeof(VCP_DATA)); 
} 
finally 
{ 
    if (handle.IsAllocated) 
        handle.Free(); 
}