I want to be able to receive some binary data over TCP/IP which consists of a known structure.
I don’t want to inter-operate with C or C++, so solutions that work for this case didn’t help me.
Unfortunately the other side cannot change the protocol.
The problem should also arise when I would try to read a binary file with a given format.
I also checked BinaryFormatter and similar but they use their own format which is not acceptable for me.
Here is a sample set of structs. I’d like to be able to reconstruct nested arrays (of known length) of structs. With the current code I get an exception:
Could not load type ‘NestedStruct’ from assembly ‘…’ because it
contains an object field at offset 2 that is incorrectly aligned or
overlapped by a non-object field.
I want to be able to send/receive (or read/write) instances of 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:
Here is my latest version:
[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
}
you must specify the ArraySubType