2013-07-06 40 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代碼。

相關問題