4

I try to Marshal a unmanaged c++ dll in c#, but the marshaller fails when creating my union.

Why does this code fail?

    [StructLayout(LayoutKind.Sequential)]
    public struct StructWithArray
    {
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public int[] MySimpleArray;
        //More Stuff
    }

    [StructLayout(LayoutKind.Explicit)]
    public struct Union
    {
        [FieldOffset(0)]
        public int Int; //Or anything else
        [FieldOffset(0), MarshalAs(UnmanagedType.Struct)]
        public StructWithArray MyStructWithArray;
        //More Structs
    }

And then constructing the Union:

Union MyUnion = new Union();

It fails if I run the code with the following Message: (Translated)

{"The Type "Union" of the Assembly [...] could not be loaded because it contained an Objectfield at Offset 0, which is not aligned correctly or got overlapped by a field which isnt a ObjectField":"Union"}

Any Suggestions?

Ps: The original code is heavily simplified to show only the Problem. There are much more Structs, and the Union is also contained by another Struct.

Kevin Bedell
  • 13,254
  • 10
  • 78
  • 114
user1431279
  • 51
  • 1
  • 5
  • Possibly an Pack issue. Try first adding attribute Pack=4 to first structure. Do you have #pragma pack in your header files for those struct. – user629926 Jun 28 '12 at 11:14
  • I dont have a #pragma in the header file. And in this code i havent even loaded the dll. this example is enough to get the error. Pack=1, Pack=4 tested, Fixed Size Tested, copying the Array directly to the union tested, all with the same result. – user1431279 Jun 28 '12 at 11:26
  • See this http://stackoverflow.com/questions/1190079/incorrectly-aligned-or-overlapped-by-a-non-object-field-error It seems that you solution is to replace first structure with [StructLayout(LayoutKind.Sequential)] public struct StructWithArray {int a;int b; //More Stuff } – user629926 Jun 28 '12 at 12:58
  • Yes, I think this is the only workaround. Or for native structures, i can use "unsafe" and "fixed array", but as i said, this only works for native structures like int, uint etc. – user1431279 Jun 28 '12 at 13:05

1 Answers1

0

Declare MySimpleArray as a fixed unsafe array:

[StructLayout(LayoutKind.Sequential)]
public unsafe struct StructWithArray
{
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
    public fixed int MySimpleArray[2];
    //More Stuff
}

[StructLayout(LayoutKind.Explicit)]
public struct Union
{
    [FieldOffset(0)]
    public int Int; //Or anything else
    [FieldOffset(0), MarshalAs(UnmanagedType.Struct)]
    public StructWithArray MyStructWithArray;
    //More Structs
}
Kaveh Shahbazian
  • 13,088
  • 13
  • 80
  • 139
  • 1
    Sadly the keyword "fixed" only works with ValueTypes like ints, bytes etc. Assuming I have an array of other structures, the "fixed" keyword doesn't work anymore. – user1431279 Jan 30 '14 at 21:30