2013-02-18 5 views
1

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

Я также проверил 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 

    } 

UPDATE:

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

[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 

    } 
+0

Вы пробовали извлекая кнопку [FieldOffset] на characterArray? – Hylaean

+0

@ Хилеян: Да. Даже не компилирует «типы полей экземпляров, отмеченные символом StrcutLayout (LayoutKind.Explicit), должны иметь атрибут FieldOffset». – Onur

+0

и переключение на LayoutKind.Sequential :) – Hylaean

ответ

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 
    } 
+0

'NestedStruct' теперь работает как ожидалось (по крайней мере, преобразование в байты). Я попробую остальные сейчас ... – Onur

+0

Мне пришлось настроить некоторые члены 'bool', но теперь это работает! – Onur