Не / Маршаллинг вложенных структур, содержащих массивы структур

Я хочу иметь возможность получать некоторые двоичные данные через TCP/IP, который состоит из известной структуры. Я не хочу взаимодействовать с C или C++, поэтому решения, которые работают для этого случая, мне не помогли. К сожалению, другая сторона не может изменить протокол. Проблема также должна возникать, когда я пытаюсь прочитать двоичный файл с заданным форматом.

Я тоже проверил BinaryFormatter и тому подобное, но они используют свой собственный формат, который для меня неприемлем.

Вот примерный набор структур. Я хотел бы иметь возможность восстанавливать вложенные массивы (известной длины) структур. С текущим кодом я получаю исключение:

Не удалось загрузить тип 'NestedStruct' из сборки '...', поскольку он содержит поле объекта со смещением 2, которое неправильно выровнено или перекрыто полем, не являющимся объектом.

Я хочу иметь возможность отправлять / получать (или читать / писать) экземпляры struct MainStruct,

    [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 244, CharSet = CharSet.Ansi)]
    public struct NestedStruct
    {

        [FieldOffset(0)]
        public Int16 someInt;

        [FieldOffset(2), MarshalAs(UnmanagedType.ByValArray, SizeConst = 242)]
        public Byte[] characterArray; // an array of fixed length 242

    }

    [StructLayout(LayoutKind.Explicit)]
    public struct OtherNestedStruct
    {
        [FieldOffset(0)]
        public Int16 someInt;
        [FieldOffset(2)]
        public Int16 someOtherInt;

    }


    [StructLayout(LayoutKind.Explicit)]
    public struct MainStruct
    {
        [FieldOffset(0)]
        public double someDouble;
        [FieldOffset(8)]
        public NestedStruct nestedContent;
        [FieldOffset(8 + 244)]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 13 * 4)]
        public OtherNestedStruct[] arrayOfStruct; // fixed array length 13

    }

ОБНОВИТЬ:

Вот моя последняя версия:

    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct NestedStruct
    {

        public Int16 someInt;

        [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.U1, SizeConst = 242)]
        public Byte[] characterArray; // an array of fixed length 242

    }

    [StructLayout(LayoutKind.Sequential , Pack=1)]
    public struct OtherNestedStruct
    {
        public Int16 someInt;
        public Int16 someOtherInt;

    }


    [StructLayout(LayoutKind.Sequential, Pack=1)]
    public struct MainStruct
    {

        public double someDouble;

        public NestedStruct nestedContent;

        [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct,  SizeConst = 13)]
        public OtherNestedStruct[] arrayOfStruct; // fixed array length 13

    }

1 ответ

Решение

Вы должны указать ArraySubType

    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct NestedStruct
    {
        public Int16 someInt;
        [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.U1, SizeConst = 242)]
        public Byte[] characterArray; // an array of fixed length 242
    }

     [StructLayout(LayoutKind.Sequential, Pack = 1)]
     public struct OtherNestedStruct
     {
         public Int16 someInt;
         public Int16 someOtherInt;

     }


     [StructLayout(LayoutKind.Sequential, Pack = 1)]
     public struct MainStruct
     {
         public double someDouble;
         public NestedStruct nestedContent;
         [MarshalAs(UnmanagedType.ByValArray, SizeConst = 13 * 4)]
         public OtherNestedStruct[] arrayOfStruct; // fixed array length 13

    }  

    static void Main(string[] args)
    {
        var x = Marshal.SizeOf(typeof(MainStruct));
        //x == 460
    } 
Другие вопросы по тегам