Не / Маршаллинг вложенных структур, содержащих массивы структур
Я хочу иметь возможность получать некоторые двоичные данные через 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
}