2013-07-06 37 views
0

我想在C#中实现一个C风格的结构用于互操作性。C#指向非托管结构与数组

这里是结构我想转换:

typedef struct 
{ 
    UINT8 TrafficClass0:4; 
    UINT8 Version:4; 
    UINT8 FlowLabel0:4; 
    UINT8 TrafficClass1:4; 
    UINT16 FlowLabel1; 
    UINT16 Length; 
    UINT8 NextHdr; 
    UINT8 HopLimit; 
    UINT32 SrcAddr[4]; 
    UINT32 DstAddr[4]; 
} DIVERT_IPV6HDR, *PDIVERT_IPV6HDR; 

这里是我的C#结构:

[StructLayoutAttribute(LayoutKind.Sequential)] 
public struct DivertIPv6Header 
{ 
    /// TrafficClass0 : 4 
    /// Version : 4 
    /// FlowLabel0 : 4 
    /// TrafficClass1 : 4 
    public uint bitvector1; 

    /// UINT16->unsigned short 
    public ushort FlowLabel1; 

    /// UINT16->unsigned short 
    public ushort Length; 

    /// UINT8->unsigned char 
    public byte NextHdr; 

    /// UINT8->unsigned char 
    public byte HopLimit; 

    /// UINT32[4] 
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 4, ArraySubType = UnmanagedType.U4)] 
    public uint[] SrcAddr; 

    /// UINT32[4] 
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 4, ArraySubType = UnmanagedType.U4)] 
    public uint[] DstAddr; 

    public uint TrafficClass0 
    { 
     get 
     { 
      return bitvector1 & 15u; 
     } 
     set 
     { 
      bitvector1 = value | bitvector1; 
     } 
    } 

    public uint Version 
    { 
     get 
     { 
      return (bitvector1 & 240u)/16; 
     } 
     set 
     { 
      bitvector1 = (value * 16) | bitvector1; 
     } 
    } 

    public uint FlowLabel0 
    { 
     get 
     { 
      return (bitvector1 & 3840u)/256; 
     } 
     set 
     { 
      bitvector1 = (value * 256) | bitvector1; 
     } 
    } 

    public uint TrafficClass1 
    { 
     get 
     { 
      return (bitvector1 & 61440u)/4096; 
     } 
     set 
     { 
      bitvector1 = (value * 4096) | bitvector1; 
     } 
    } 
} 

这里唯一的问题是,我需要一个指针声明本结构,以便我可以重叠它的数据。

如果我尝试声明指针我得到这个编译时错误:

cannot declare pointer to non-unmanaged type. 

任何想法?

+0

非常不可能你需要一个指针,但是你没有给出足够的信息。 “重叠”表明你实际上想要声明一个联合,你用[StructLayout(LayoutKind.Explicit)]属性来做到这一点。但是这仍然是数组成员的一个问题,出于同样的原因,你不能声明一个指向这个结构的指针,你需要用* fixed *关键字将它们声明为固定大小的缓冲区。 –

+0

我对工会不感兴趣。我有一个指向byte *数组的指针,我想将它转换为DivertIPv6Header *。 – Paul

+0

这就是Marshal.PtrToStructure(),没有使用* fixed *就可以正常工作。你没有帮助我们通过对你的要求如此模糊来帮助你。 –

回答

0

使用Marshal.PtrToStructure

 var bytes = yourUnmanagedByteArray; 

     fixed (byte* b = bytes) 
      return (T)Marshal.PtrToStructure(new IntPtr(b), typeof(DivertIPv6Header)); 

你可以把它没有fixed缓冲工作也一样,如果你不希望使用unsafe代码。

相关问题