Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Incorrectly aligned or overlapped by a non-object field error

I'm trying to create the following structure:

    [StructLayout(LayoutKind.Explicit, Size=14)]
    public struct Message
    {
        [FieldOffset(0)]
        public ushort X;
        [FieldOffset(2)]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst=5)]
        private ushort[] Y;
        [FieldOffset(12)]
        public ushort Z;
    }

and I get the following error:

Could not load type 'Message' from assembly because it contains an object field at offset 4 that is incorrectly aligned or overlapped by a non-object field.

Does anyone know why this is causing an error?

Note: I can not use Pack because I'm working with the compact framework. Thanks.

like image 906
SwDevMan81 Avatar asked Jul 27 '09 19:07

SwDevMan81


2 Answers

The CF Marshaler isn't so good at this type of thing and what you're attempting is unsupported. The problem is that it knows that the first element is unaligned, but it seems to not understand that each element in the array would also be unaligned.

You can see the behavior works in this example:

[StructLayout(LayoutKind.Explicit, Size = 14)]
public struct Message
{
    [FieldOffset(0)]
    public ushort X;

    [FieldOffset(2)]
    private ushort Y1;

    [MarshalAs(UnmanagedType.LPArray)]
    [FieldOffset(4)]
    private ushort[] Y2;

    [FieldOffset(12)]
    public ushort Z;
}

For this type of structure, I never let the marshaler try to handle each of the members anyway. The structure is small, so break out each individual item like this:

[StructLayout(LayoutKind.Explicit, Size = 14)]
public struct Message
{
    [FieldOffset(0)]
    public ushort X;

    [FieldOffset(2)]
    private ushort Y1;

    [FieldOffset(4)]
    private ushort Y2;

    [FieldOffset(6)]
    private ushort Y3;

    [FieldOffset(8)]
    private ushort Y4;

    [FieldOffset(10)]
    private ushort Y5;

    [FieldOffset(12)]
    public ushort Z;
}

or use a simulated "union" like this:

public struct Y
{
    public ushort a;
    public ushort b;
    public ushort c;
    public ushort d;
    public ushort e;
}

[StructLayout(LayoutKind.Explicit, Size = 14)]
public struct Message
{
    [FieldOffset(0)]
    public ushort X;

    [FieldOffset(2)]
    private Y Y;

    [FieldOffset(12)]
    public ushort Z;
}
like image 88
ctacke Avatar answered Oct 27 '22 00:10

ctacke


The problem is occurring because your array is overlapping "X". ulong, in C#, is UInt64 (in C++, ulong is UInt32), so it's actually 8 bytes.

If you change your second FieldOffset to 8, or changed X to uint, this will go away.

like image 37
Reed Copsey Avatar answered Oct 26 '22 22:10

Reed Copsey