2014-10-06 98 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