Union Structure Marshaling


J

Jeffrey B. Holtz

THANK YOU 1,000 fold if anyone can help me in this Marshalling:

C structure
===========
struct mystruct {
char tag;
char field1;
char field2;
char field3;
long field4;
union struct2 tagData;
}

union struct2 {
struct struct3 union1;
struct struct4 union2;
}

struct struct3 {
long id;
char flags;
char size;
char data[MAX_SIZE];
}
struct struct4 {
char byte1;
char byte2;
char byte3;
}

C# Attempt
==========
[StructLayout (LayoutKind.Explicit, Pack=1, CharSet=CharSet.Ansi)]
public struct oldStruct
{
[FieldOffset (0)] public byte tag;
[FieldOffset (1)] public byte field1;
[FieldOffset (2)] public byte field2;
[FieldOffset (3)] public byte field3;
[FieldOffset (4)] public uint field4;

/* union members */
// VRcvMsg
[FieldOffset (8) ] public uint id;
[FieldOffset (12)] public byte flags;
[FieldOffset (13)] public byte dlc;
[FieldOffset (14)] public byte [] data;
// union2
[FieldOffset (8) ] public byte byte1;
[FieldOffset (9) ] public byte byte2;
[FieldOffset (10)] public byte byte3;
}


Although this compiles, It cannot instantiate oldStruct because the
data is not aligned properly. I've thought of just putting MAX_SIZE
data parameters and brute force but.....

THANKS to anyone out there
 
Ad

Advertisements

M

Ming Chen

Hi, Jeffrey.
Try the following declaration for the oldStruct (change 100 to MAX_SIZE
defined in your C code):

[StructLayout (LayoutKind.Explicit, Pack=1, CharSet=CharSet.Ansi)]
public struct oldStruct
{
[FieldOffset (0)] public byte tag;
[FieldOffset (1)] public byte field1;
[FieldOffset (2)] public byte field2;
[FieldOffset (3)] public byte field3;
[FieldOffset (4)] public uint field4;

/* union members */
// VRcvMsg
[FieldOffset (8) ] public uint id;
[FieldOffset (12)] public byte flags;
[FieldOffset (13)] public byte dlc;
[FieldOffset (14), MarshalAs(UnmanagedType.ByValArray, SizeConst=100)]
public byte [] data;
// union2
[FieldOffset (8) ] public byte byte1;
[FieldOffset (9) ] public byte byte2;
[FieldOffset (10)] public byte byte3;
}

Regards
Ming Chen
 
J

Jeffrey Holtz

Thanks for the response but that's what I tried to begin with.
The response that I get durring runtime is:

An unhandled exception of type 'System.TypeLoadException' occurred in
CANdotNET.exe

Additional information: Could not load type oldVEvent2 from assembly
CANdotNET, Version=1.0.1728.30204, Culture=neutral, PublicKeyToken=null
because it contains an object field at offset 14 that is incorrectly
aligned or overlapped by a non-object field.


The P/Invoke function is:
=========================
[DllImport("Unmanaged.dll")]
private static extern short csFunc(int nHandle, out oldStruct oStruct);

And in the Unmanaged dll I have:
UNAMANGED_API short csFunc(long nHandle, mystruct *pStruct);
 
Ad

Advertisements

M

Ming Chen

Hi, Jeffrey.
Didn't notice the error message last time. :)
Try this:

[StructLayout (LayoutKind.Explicit, Pack=1, CharSet=CharSet.Ansi)]
public struct oldStruct
{
[FieldOffset (0)] public byte tag;
[FieldOffset (1)] public byte field1;
[FieldOffset (2)] public byte field2;
[FieldOffset (3)] public byte field3;
[FieldOffset (4)] public uint field4;

/* union members */
// VRcvMsg
[FieldOffset (8) ] public uint id;
[FieldOffset (12)] public byte flags;
[FieldOffset (13)] public byte dlc;
[FieldOffset (14), MarshalAs(UnmanagedType.ByValArray, SizeConst=100)]
public IntPtr data;

// union2
[FieldOffset (8) ] public byte byte1;
[FieldOffset (9) ] public byte byte2;
[FieldOffset (10)] public byte byte3;
}

To allocate the memory for data, use Marshal.AllocHGlobal. And then use
Marshal.FreeHGlobal to free it.

Regards
Ming Chen
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top