I'm trying to send a network packet of data to a hardware device. I would like to use a slick, object oriented approach so I can work with it at a high level. The packet has several fields of variable length. Obviously the byte layout is very particular.
Here's a struct representing the packet I need to send:
[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[]
can be any length, I'm fixing it to 8 bytes as a starter.
Here's my attempt at creating a byte[]
to send it via 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();
}
}
But I receive:
ArgumentException : Object contains non-primitive or non-blittable data.
I thought setting SizeConst
in the struct would take care of this? Anyways, I'm more lost than this because the hardware device is expecting a variable length packet, and I'd like to take advantage of that.
I can manually put together the packet byte-by-byte and everything works great. But I know there has got to be a better way, and that I must be going down the wrong path.
Any ideas?