Reputation: 5349
Is there a way in C# to serialize a struct to a binary stream (MemoryStream) such that the binary representation is equivalent to how the struct is visually layed out (i.e. no padding)?
In C/C++, you use #pragma commands to tell the compiler to pack the struct's so that there is no padding between the fields. This is helpful if you have two apps passing messages back and forth via sockets. With packing disabled, you can simply "send" the contents of the struct over the socket and not have to worry about packing each field individually into a binary buffer (also have to do endianness swapping if necessary).
Upvotes: 3
Views: 6036
Reputation: 6437
You can use the [StructLayout]
and [FieldOffset]
attributes to control the way your struct's fields are packed (google 'marshalling' for more info), and then use the following to generate a binary representation of your struct that can be sent through your network stream:
public static byte[] GetBytes<TStruct>(TStruct data) where TStruct : struct
{
int structSize = Marshal.SizeOf(typeof(TStruct));
byte[] buffer = new byte[structSize];
GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
Marshal.StructureToPtr(data, handle.AddrOfPinnedObject(), false);
handle.Free();
return buffer;
}
The downsides:
Upvotes: 1
Reputation: 20076
Not unless you use unsafe code. Use Protocol Buffers or Thrift or something like that; I wouldn't recommend .NET built-in binary serialization based on my experience. You could also serialize/deserialize with BinaryWriter/BinaryReader
(use reflection or pre-generate serialization code). As for packing, you can control it with the [StructLayout]
attribute.
Upvotes: 3