2

Possible Duplicate:
C++ union in C#

Code in C:

typedef struct _EVENT_HEADER {
USHORT              Size;                   // Event Size
USHORT              HeaderType;             // Header Type
USHORT              Flags;                  // Flags
USHORT              EventProperty;          // User given event property
ULONG               ThreadId;               // Thread Id
ULONG               ProcessId;              // Process Id
LARGE_INTEGER       TimeStamp;              // Event Timestamp
GUID                ProviderId;             // Provider Id
EVENT_DESCRIPTOR    EventDescriptor;        // Event Descriptor
union {
    struct {
        ULONG       KernelTime;             // Kernel Mode CPU ticks
        ULONG       UserTime;               // User mode CPU ticks
    } DUMMYSTRUCTNAME;
    ULONG64         ProcessorTime;          // Processor Clock 
                                            // for private session events
} DUMMYUNIONNAME;
GUID                ActivityId;             // Activity Id

} EVENT_HEADER, *PEVENT_HEADER;

I converted anything but the union. How to convert it to C#?

Community
  • 1
  • 1
Moti
  • 65
  • 4

2 Answers2

3

You can use [StructLayout(LayoutKind.Explicit)] to explicitly place the members at the correct offsets.

Here is an example from an answer I provided previously

[StructLayout(LayoutKind.Explicit)]
public struct CharUnion
{
  [FieldOffset(0)] public char UnicodeChar;
  [FieldOffset(0)] public byte AsciiChar;
}

[StructLayout(LayoutKind.Explicit)]
public struct CharInfo
{
  [FieldOffset(0)] public CharUnion Char;
  [FieldOffset(2)] public short Attributes;
}
Community
  • 1
  • 1
Chris Taylor
  • 52,623
  • 10
  • 78
  • 89
1

C# doesn't natively support the C/C++ notion of unions. You can however use the StructLayout(LayoutKind.Explicit) and FieldOffset attributes to create equivalent functionality.

Regarding to union: in the code below you can see that Kernel and ProcessorTime have the same offset. LargeInteger is also a good example of union implementation in C#.

EventHeader

[StructLayout(LayoutKind.Explicit)]
public struct EventHeader
{
    [FieldOffset(0)]
    public ushort Size;

    [FieldOffset(2)]
    public ushort HeaderType;

    [FieldOffset(4)]
    public ushort Flags;

    [FieldOffset(6)]
    public ushort EventProperty;

    [FieldOffset(8)]
    public uint ThreadId;

    [FieldOffset(12)]
    public uint ProcessId;

    [FieldOffset(16)]
    public LargeInteger TimeStamp;

    [FieldOffset(24)]
    public Guid ProviderId;

    [FieldOffset(40)]
    public Guid EventDescriptor;

    [FieldOffset(52)]
    public uint KernelTime;

    [FieldOffset(56)]
    public uint UserTime;

    [FieldOffset(52)]
    public ulong ProcessorTime;

    [FieldOffset(60)]
    public Guid ActivityId;
}

LargeInteger

[StructLayout(LayoutKind.Explicit, Size = 8)]
public struct LargeInteger
{
    [FieldOffset(0)]
    public long QuadPart;

    [FieldOffset(0)]
    public uint LowPart;

    [FieldOffset(4)]
    public uint HighPart;
}

EventDescriptor

[StructLayout(LayoutKind.Sequential)]
public struct EventDescriptor
{
    public ushort Id;

    public byte Level;

    public byte Channel;

    public byte LevelSeverity;

    public byte Opcode;

    public ushort Task;

    public uint Keyword;
}

Disclaimer: I just made this code. Didn't test it. The code may have errors.

Alex Aza
  • 76,499
  • 26
  • 155
  • 134
  • interesting, so each of the structs: `EventHeader` and `LargeInteger` are akin to a bit array (if that were a datatype) ...??? hhmmm ... new datatype ... dangerous! – IAbstract Jun 12 '11 at 17:53
  • @IAbstract - not sure I understood your comment. `EventHeader` and `LargeInteger` are structs and don't have much in common with `BitArray`. – Alex Aza Jun 12 '11 at 18:52
  • That's what I was asking ... but, alas, I was unaware of the BitArray class. And I see the differences now. Thanks ... – IAbstract Jun 12 '11 at 21:23