2

我正在尝试在 C# 中创建以下结构,它是一个基于 C 的复杂结构,我尝试了大多数编组选项,但我总是得到“System.TypeLoadException”。

(附加信息:无法从程序集“WindowsFormsApplication1,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null”加载类型“WindowsFormsApplication1.COMPLEX_STRUCT”,因为它包含偏移量 8 处的对象字段,该对象字段不正确地对齐或重叠-对象字段。)

关于 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;
4

1 回答 1

1

After looking at your original structs and looking at other implementations for IPV4 and IPV6 structs, I see that other implementations use byte[4] for IPV4's address.

I can't guarantee the results will be correct, but if you are able to change IPV4 and IPV6 to both use a byte[] instead, your error will go away.

You cannot mix and match as you found. The only other option I can think of to try is see if it will allow you to use IntPtr to get the location of the memory and then use Marshal.Copy to grab the data.

Even though once you get them working, I cannot guarantee your results will be correct though.

于 2014-10-06T21:24:45.993 回答