Я пытаюсь отправить сетевой пакет данных на аппаратное устройство. Я хотел бы использовать гладкий, объектно-ориентированный подход, чтобы я мог работать с ним на высоком уровне. Пакет имеет несколько полей переменной длины. Очевидно, что структура байтов очень специфична.
Вот структура, представляющая пакет, который мне нужно отправить:
[StructLayout(LayoutKind.Sequential)]
public struct Packet
{
public UInt16 Instruction;
public UInt16 Length; //length of data field
public UInt32 SessionHandle;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] SenderContext;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] MessageData;
}
MessageData[]
может быть любой длины, я фиксирую это как 8 байт в качестве стартера.
Вот моя попытка создать byte[]
для отправки через Socket:
public static byte[] ToBytes(Packet ep)
{
Byte[] bytes = new Byte[Marshal.SizeOf(typeof(Packet))];
GCHandle pinStructure = GCHandle.Alloc(ep, GCHandleType.Pinned);
try
{
Marshal.Copy(pinStructure.AddrOfPinnedObject(), bytes, 0, bytes.Length);
return bytes;
}
finally
{
pinStructure.Free();
}
}
Но я получаю:
ArgumentException : Object contains non-primitive or non-blittable data.
Я думал, что установка SizeConst
в структуре позаботится об этом? В любом случае, я более потерян, чем это, потому что аппаратное устройство ожидает пакет переменной длины, и я хотел бы воспользоваться этим.
Я могу вручную собрать пакет за байтом, и все отлично работает. Но я знаю, что должен быть лучший путь, и я должен идти по неверному пути.
Есть идеи?