2011-06-12 56 views
2

可能重复:
C++ union in C#需要帮助在C从工会转换为C#

代码在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; 

我转换什么,但工会。如何将其转换为C#?

+0

使用StructLayout&FieldOffset属性。 – 2011-06-12 17:11:01

+0

作为一个侧面说明,在c#中创建一个可变的严格通常是一个错误.. – 2011-06-12 17:34:49

+0

@Marc,我想在这种情况下,op需要P/Invoke这个选项是有限的。 – 2011-06-12 17:42:35

回答

1

C#本身不支持工会的C/C++概念。但是,您可以使用StructLayout(LayoutKind.Explicit)和FieldOffset属性来创建等效的功能。

关于union:在下面的代码中,您可以看到KernelProcessorTime具有相同的偏移量。 LargeInteger也是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; 
} 

放弃呃:我只是做了这个代码。没有测试它。该代码可能有错误。

+0

有趣,所以每个结构:'EventHeader'和'LargeInteger'类似于一个位数组(如果它是一个数据类型)... ??? hhmmm ...新的数据类型...危险! – IAbstract 2011-06-12 17:53:36

+0

@IAbstract - 不知道我理解你的评论。 'EventHeader'和'LargeInteger'是结构体,与'BitArray'没有太大共同之处。 – 2011-06-12 18:52:59

+0

这就是我所要求的......但是,唉,我不知道BitArray类。我现在看到了差异。谢谢 ... – IAbstract 2011-06-12 21:23:12

3

您可以使用[StructLayout(LayoutKind.Explicit)]将成员显式放置在正确的偏移处。

这里给出一个从answer一个例子,我提供先前

[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; 
}