简体   繁体   English

C# 嵌套结构编组 - 对象

[英]C# nested structure marshaling - object

I have the following nested structures.我有以下嵌套结构。

[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;
};

I need to copy a byte array to this structure, so I tried the following我需要将一个字节数组复制到这个结构中,所以我尝试了以下操作

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();
}

But GCHandle.Alloc() returns the error "An unhandled exception of type System.Argument.Execption" occurred in mscorlib.dll.但是 GCHandle.Alloc() 返回错误“类型 System.Argument.Execption 的未处理异常”发生在 mscorlib.dll 中。 Additional information: Object contains non-primitive or non-blittable data.附加信息:对象包含非原始或非 blittable 数据。

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(); 
}

First of all, ERROR_ITEM[] is a managed array, so that's not a blittable structure.首先, ERROR_ITEM[] 是一个托管数组,所以它不是一个 blittable 结构。 It's just a managed reference.这只是一个托管引用。 The memory that reference points to has a syncblock, method table pointer, and a length specifier sitting in front of the actual elements.引用指向的内存有一个同步块、方法表指针和一个位于实际元素前面的长度说明符。

However, using 'fixed' ( https://msdn.microsoft.com/en-us/library/zycewsya.aspxhttps://msdn.microsoft.com/en-us/library/zycewsya.aspx ) isn't going to help (but check me on that).但是,使用“固定”( https://msdn.microsoft.com/en-us/library/zycewsya.aspxhttps://msdn.microsoft.com/en-us/library/zycewsya.aspx )不会帮助(但请检查我)。 To get past this error, since ERROR_ITEM [] is of a fixed length, just replace the array with 16 of those ERROR_ITEM fields.为了克服这个错误,因为ERROR_ITEM [] 的长度是固定的,只需将数组替换为ERROR_ITEM字段中的 16 个。 You can still use array syntax against the address of the first ERROR_ITEM ( ERROR_ITEM* ) to access subsequent elements.您仍然可以针对第一个ERROR_ITEM ( ERROR_ITEM* ) 的地址使用数组语法来访问后续元素。

Alternately, just compute the size of all 16 elements, but include only the first one as a field, then specify the Size parameter on the StructLayout attribute for ERROR_DATA so that it's big enough to hold them all.或者,只计算所有 16 个元素的大小,但只包含第一个作为字段,然后在StructLayout属性上为ERROR_DATA指定Size参数,以便它足够大以容纳所有ERROR_DATA

Also, Resharper sometimes whines about nested stuff when the actual compiler is perfectly happy with it.此外,当实际的编译器对嵌套内容非常满意时,Resharper 有时会抱怨嵌套内容。 But this is caused by it being an array.但这是由它是一个数组引起的。 Even a fixed unsafe embdedded array makes C# think it's unblittable in my experience.根据我的经验,即使是固定的不安全的嵌入式数组也让 C# 认为它是不可分割的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM