2014-10-06 175 views
0

我想在C#中創建下面的結構,它是一個基於C的複雜結構,我嘗試了大部分編組選項,但我總是得到'System。 TypeLoadException」。 (附加信息:無法從程序集'WindowsFormsApplication1,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null'加載'WindowsFormsApplication1.COMPLEX_STRUCT'類型,因爲它包含不正確對齊的偏移8處的對象字段或通過非對象場重疊)結構不正確對齊:System.TypeLoadException

關於IPV6_ADDR結構,我都嘗試LayoutKind.Explicit和LayoutKind.Sequential, 無一不:

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)] 
public string Addr; 

[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] 
public byte[] Addr; 

我在x64機器上,但IPV6_ADDR結構被對齊到8個字節,所以我無法弄清楚是什麼問題。

[StructLayout(LayoutKind.Sequential, Pack = 1)] 
public struct IPV4_ADDR 
{ 
    public uint Addr; 
    public uint SubnetNumBits; 
}; 

[StructLayout(LayoutKind.Explicit, Pack = 1)] 
public struct IPV6_ADDR 
{ 
    [FieldOffset(0)] 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)] 
    public string Addr; 
    [FieldOffset(16)] 
    public uint SubnetNumBits; 
}; 

[StructLayout(LayoutKind.Explicit, Pack = 1)] 
public struct COMPLEX_STRUCT 
{ 
    [FieldOffset(0)] 
    public byte A; 

    [FieldOffset(1)] 
    public byte B; 

    [FieldOffset(2)] 
    public byte C; 

    [FieldOffset(3)] 
    public byte D; 

    [FieldOffset(4)] 
    public byte E; 

    [FieldOffset(8)] 
    public IPV4_ADDR IPv4; 

    [FieldOffset(8)] 
    public IPV6_ADDR IPv6; 

    [FieldOffset(28)] 
    public ushort F; 
} 

原來的C結構我試圖模仿:

typedef struct _IPV4_ADDR 
{ 
    uint32_t Addr; 
    uint32_t SubnetNumBits; 
} IPV4_ADDR, *PIPV4_ADDR; 

typedef struct _IPV6_ADDR 
{ 
    uint8_t Addr[16]; 
    uint32_t SubnetNumBits; 
} IPV6_ADDR, *PIPV6_ADDR; 

typedef struct _COMPLEX_STRUCT 
{ 
    uint8_t A; 
    uint8_t B; 
    uint8_t C; 
    uint8_t D; 
    uint8_t E; 
    uint8_t Rsvd[3]; 
    union { 
     IPV4_ADDR IPv4; 
     IPV6_ADDR IPv6; 
    } u; 
    uint16_t F; 
} COMPLEX_STRUCT, *PCOMPLEX_STRUCT; 
+0

@TyCobb有。由於字符串是由.NET運行時管理的,因此不能覆蓋具有字符串的結構,而該字符串不具有相同本地偏移量的字符串。 – 2014-10-06 23:20:25

+0

OK Thx,我真的不介意從字符串切換到byte []/char [],但我也嘗試過,並且仍然不好 – n00b 2014-10-07 05:24:54

+0

我已經將原始結構添加到您的問題中。請刪除你的答案。 – TyCobb 2014-10-07 15:08:03

回答

1

看着你原來的結構,並尋找其它的實現IPv4和IPv6結構後,我看到其他實現使用byte[4]爲IPV4的地址。

我無法保證結果是正確的,但如果您能夠將IPV4和IPV6更改爲同時使用byte[],則您的錯誤將消失。

你不能混合和匹配,因爲你發現。我能想到的唯一的其他選擇是嘗試查看是否允許您使用IntPtr來獲取內存的位置,然後使用Marshal.Copy來獲取數據。

即使一旦你讓他們工作,我不能保證你的結果將是正確的。

+0

我想將它們聯合起來,我正在轉換一個具有IPV4和IPV6字段聯合的C結構。 我真的不介意從字符串切換到byte []/char [],但我也嘗試過,但仍然沒有好轉 – n00b 2014-10-07 05:16:28

+0

@ n00b可能唯一的方法是如果將字節[] 2'ulongs'。當需要使用數據(結構體上的方法)時,有一個FieldOffset(0)和FieldOffset(8),然後將這兩個long合併回單個字節[]中。 – TyCobb 2014-10-07 05:43:55

+0

@ n00b您還可以顯示您試圖模仿的實際結構嗎?我開始認爲你是IPVx結構體應該使用'IntPtr'而不是'unint'和'string'。 – TyCobb 2014-10-07 05:51:23