Marshalling a struct that contains a union...


DevX Home    Today's Headlines   Articles Archive   Tip Bank   Forums   

Results 1 to 5 of 5

Thread: Marshalling a struct that contains a union...

  1. #1
    Tim Overbay Guest

    Marshalling a struct that contains a union...

    Here's the C++ definition of a structure I'm trying to marshal for DirectX:

    typedef struct _D3DMATRIX {
    union {
    struct {
    float _11, _12, _13, _14;
    float _21, _22, _23, _24;
    float _31, _32, _33, _34;
    float _41, _42, _43, _44;
    };
    float m[4][4];
    };
    } D3DMATRIX;

    I'm trying to define this in C# and this is what I came up with:

    [StructLayout(LayoutKind.Explicit)]
    public struct D3DMATRIX
    {
    [FieldOffset(0)] public float _11;
    [FieldOffset(4)] public float _12;
    [FieldOffset(8)] public float _13;
    [FieldOffset(12)] public float _14;

    [FieldOffset(16)] public float _21;
    [FieldOffset(20)] public float _22;
    [FieldOffset(24)] public float _23;
    [FieldOffset(28)] public float _24;

    [FieldOffset(32)] public float _31;
    [FieldOffset(36)] public float _32;
    [FieldOffset(40)] public float _33;
    [FieldOffset(44)] public float _34;

    [FieldOffset(48)] public float _41;
    [FieldOffset(52)] public float _42;
    [FieldOffset(56)] public float _43;
    [FieldOffset(60)] public float _44;

    [FieldOffset(0)]
    [MarshalAs(UnmanagedType.LPArray, SizeConst=16)]
    public float[,] m;
    }

    When I try to use D3DMATRIX, I get the following error:

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

    Can anybody tell me what I'm missing here?

    Thanks,

    Tim



  2. #2
    Rob Teixeira Guest

    Re: Marshalling a struct that contains a union...



    You can't overlap an object field (array is an object) with a value type
    field.

    My suggestion is to:
    1) use one or the other. you rarely ever need both
    2) create two seperate structures and use a custom marshaller that can turn
    one into the other for the sake of passing it to a method

    -Rob

    "Tim Overbay" <toverbay@pbsj.com> wrote:
    >Here's the C++ definition of a structure I'm trying to marshal for DirectX:
    >
    > typedef struct _D3DMATRIX {
    > union {
    > struct {
    > float _11, _12, _13, _14;
    > float _21, _22, _23, _24;
    > float _31, _32, _33, _34;
    > float _41, _42, _43, _44;
    > };
    > float m[4][4];
    > };
    > } D3DMATRIX;
    >
    >I'm trying to define this in C# and this is what I came up with:
    >
    > [StructLayout(LayoutKind.Explicit)]
    > public struct D3DMATRIX
    > {
    > [FieldOffset(0)] public float _11;
    > [FieldOffset(4)] public float _12;
    > [FieldOffset(8)] public float _13;
    > [FieldOffset(12)] public float _14;
    >
    > [FieldOffset(16)] public float _21;
    > [FieldOffset(20)] public float _22;
    > [FieldOffset(24)] public float _23;
    > [FieldOffset(28)] public float _24;
    >
    > [FieldOffset(32)] public float _31;
    > [FieldOffset(36)] public float _32;
    > [FieldOffset(40)] public float _33;
    > [FieldOffset(44)] public float _34;
    >
    > [FieldOffset(48)] public float _41;
    > [FieldOffset(52)] public float _42;
    > [FieldOffset(56)] public float _43;
    > [FieldOffset(60)] public float _44;
    >
    > [FieldOffset(0)]
    > [MarshalAs(UnmanagedType.LPArray, SizeConst=16)]
    > public float[,] m;
    > }
    >
    >When I try to use D3DMATRIX, I get the following error:
    >
    > "Could not load type D3DMATRIX from assembly 0
    > because it contains an object field at offset 0 that is
    > incorrectly aligned or overlapped by a non-object field."
    >
    >Can anybody tell me what I'm missing here?
    >
    >Thanks,
    >
    >Tim
    >
    >



  3. #3
    Tim Overbay Guest

    Re: Marshalling a struct that contains a union...

    Hrmm... that was such an elegant way of implementing both access methods,
    too...

    I wouldn't mind just implementing the array. I think the _11, _12 etc.
    members are a little hokey, but I'm not sure how DirectX accesses the
    matrix. Do the DirectX functions use the array or the _11, _12 members when
    dealing with D3DMATRIX structures? Does it even matter?

    Thanks,

    Tim

    "Rob Teixeira" <RobTeixeira@@msn.com> wrote in message
    news:3c7d0c87$1@10.1.10.29...
    >
    >
    > You can't overlap an object field (array is an object) with a value type
    > field.
    >
    > My suggestion is to:
    > 1) use one or the other. you rarely ever need both
    > 2) create two seperate structures and use a custom marshaller that can

    turn
    > one into the other for the sake of passing it to a method
    >
    > -Rob




  4. #4
    Tim Overbay Guest

    Re: Marshalling a struct that contains a union...

    I kinda got around this issue by implementing the _mn access methods with
    properties:
    public float _12
    {
    get {return m[0,1];}
    set {m[0,1] = value;}
    }
    . . . etc . . .

    The next problem I encountered was that there didn't seem to be any way to
    initialize the matrix array without using parameterized constructors. So I
    also converted the struct to a class to get around this. According to the
    Interop docs, I should be able to marshal it as a structure. The only
    difference I can think of is that I have to explicitly initialize my
    D3DMATRIX objects with New now. Not nearly as 'neat' as I had hoped, but I
    think this should work..

    Thanks,

    Tim



    "Tim Overbay" <toverbay@pbsj.com> wrote in message
    news:3c7d23e2@10.1.10.29...
    > Hrmm... that was such an elegant way of implementing both access methods,
    > too...
    >
    > I wouldn't mind just implementing the array. I think the _11, _12 etc.
    > members are a little hokey, but I'm not sure how DirectX accesses the
    > matrix. Do the DirectX functions use the array or the _11, _12 members

    when
    > dealing with D3DMATRIX structures? Does it even matter?
    >
    > Thanks,
    >
    > Tim
    >
    > "Rob Teixeira" <RobTeixeira@@msn.com> wrote in message
    > news:3c7d0c87$1@10.1.10.29...
    > >
    > >
    > > You can't overlap an object field (array is an object) with a value type
    > > field.
    > >
    > > My suggestion is to:
    > > 1) use one or the other. you rarely ever need both
    > > 2) create two seperate structures and use a custom marshaller that can

    > turn
    > > one into the other for the sake of passing it to a method
    > >
    > > -Rob

    >
    >




  5. #5
    Rob Teixeira Guest

    Re: Marshalling a struct that contains a union...



    Shouldn't matter at all. In fact, off the top of my head, in memory both
    signatures look the same. It was defined this way so C++ programmers could
    either use array or field access to the structure.

    -Rob

    "Tim Overbay" <toverbay@pbsj.com> wrote:
    >Hrmm... that was such an elegant way of implementing both access methods,
    >too...
    >
    >I wouldn't mind just implementing the array. I think the _11, _12 etc.
    >members are a little hokey, but I'm not sure how DirectX accesses the
    >matrix. Do the DirectX functions use the array or the _11, _12 members when
    >dealing with D3DMATRIX structures? Does it even matter?
    >
    >Thanks,
    >
    >Tim



Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center
 
 
FAQ
Latest Articles
Java
.NET
XML
Database
Enterprise
Questions? Contact us.
C++
Web Development
Wireless
Latest Tips
Open Source


   Development Centers

   -- Android Development Center
   -- Cloud Development Project Center
   -- HTML5 Development Center
   -- Windows Mobile Development Center