Структура неправильно выровнена: System.TypeLoadException

Я пытаюсь создать следующую структуру в C#, это сложная структура, основанная на C, я пробовал большинство вариантов маршалинга, но я всегда получаю 'System.TypeLoadException'.

(Дополнительная информация: не удалось загрузить тип "WindowsFormsApplication1.COMPLEX_STRUCT" из сборки "WindowsFormsApplication1, версия =1.0.0.0, Culture= нейтральный, PublicKeyToken=null", поскольку он содержит поле объекта со смещением 8, которое неправильно выровнено или перекрыто не -объект.)

Что касается структуры IPV6_ADDR, я попробовал и LayoutKind.Explicit и LayoutKind.Sequential, и оба:

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

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

Я на машине с 64-разрядной версией, но структура 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;

1 ответ

Посмотрев на ваши исходные структуры и просмотрев другие реализации для структур IPV4 и IPV6, я вижу, что другие реализации используют byte[4] для адреса IPV4.

Я не могу гарантировать, что результаты будут правильными, но если вы сможете изменить IPV4 и IPV6, чтобы использовать оба byte[] вместо этого ваша ошибка исчезнет.

Вы не можете смешивать и сочетать, как вы нашли. Единственный другой вариант, который я могу попробовать - посмотреть, позволит ли он вам использовать IntPtr чтобы получить местоположение памяти, а затем используйте Marshal.Copy, чтобы получить данные.

Даже если вы заставите их работать, я не могу гарантировать, что ваши результаты будут правильными.

Другие вопросы по тегам