Marshalling array of structs vs classes

荒凉一梦 提交于 2020-01-02 06:55:22

问题


I want to read a native struct into a C# type using Marshalling. My method to Marshal structs is like so:

T ReadObject<T>(BinaryReader br) {
    var bytes = br.ReadBytes(Marshal.SizeOf(typeof(T)));
    var handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
    try {
        return (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
    }
    finally {
        handle.Free();
    }
}

Now this works fine in general, the problem arises with the following type:

[StructLayout(LayoutKind.Sequential, Pack=1)]
class SubData {
    public short A1;
    public short A2;
}

[StructLayout(LayoutKind.Sequential, Pack=1)]
class Data {
    public short Id;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst=3)]
    public SubData[] SubDatas;
}

Note that this works fine if SubData is a struct! But if SubData is a class, it causes Marshal.PtrToStructure to throw a FatalExecutionEngineError. I'd like to stick with classes because sometimes my types have default values and structs cannot have field initializers nor default constructors, and also some of these types are rather large.

Thanks for the help.

Edit: the error message is "The runtime has encountered a fatal error. The address of the error was at 0x6af99aec, on thread 0x348. The error code is 0xc0000005. This error may be a bug in the CLR or in the unsafe or non-verifiable portions of user code. Common sources of this bug include user marshaling errors for COM-interop or PInvoke, which may corrupt the stack."


回答1:


A class is a reference type, thus when using Marshal.PtrToStructure it will copy a pointer and no values at the position of Subdata.
When declaring Subdata as struct, then the actual values of subdata will be copied.
Thus when doing the Marshalling, you must use a struct. You might still have a class as well, which will take the struct version in a constructor.
You can for instance prove this by using

sizeof

to see that the sizes will differ.



来源:https://stackoverflow.com/questions/9883308/marshalling-array-of-structs-vs-classes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!