title: Serializing / Marshalling simple objects in C# to send over network, for an unmanaged C++ application to read
body: <p>I am writing a C# application that needs to communicate with a unmanaged C++ application over the network using pre-defined messages. Every message starts with a message id and length. </p>
  
  <pre><code>Byte 0  MessageId
  Byte 1  Length
  </code></pre>
  
  <p>After that, it is different for each message. Such as a message to set the time, will be</p>
  
  <pre><code>Byte 0      MessageId
  Byte 1      Length
  Byte 2..5   Time
  </code></pre>
  
  <p>Starting out, I figured I would just create a base class which all other messages would inherit from, which would have a method to "serialize" it:</p>
  
  <pre><code>public class BaseMessage
  {
      public virtual byte MessageId { get; }
      public virtual byte Length { get; }
  
      public byte[] GetAsMessage()
      {
          ...
      }
  }
  
  public class SetTimeMessage : BaseMessage
  {
      public override byte MessageId =&gt; 1;
      public override byte Length {get; private set; }
      public byte[] Time {get; private set; }
  
      public SetTimeMessage(byte[] time)
      {
          ...
      }
  }
  </code></pre>
  
  <p>In the C++ code, if I create a <code>SetTimeMessage</code> and want to send it over the network, a method like <code>GetAsMessage</code> which is defined on the base class is called, which will simply copy the contents of the object into a buffer. This works for all derived types of <code>BaseMessage</code>.</p>
  
  <p>How can I do something similar in C#? I tried using the <code>[Serializable]</code> attribute and the <code>BinaryFormatter</code>, but it returned a huge byte array, not just the 6 bytes that the values actually contain.</p>
  
  <p>I also looked into <code>Marshalling</code>, but it only seems to work with structs? If so, it seems like a lot of work needs to be done for each message type, since structs don't support inheritance (there are many messages I need to implement).</p>
  
  <p>I will also receive messages back in the same format, which need to be deserialized back to an object. Anybody know of a neat way of achieving what I'm after?</p>
  
  <p><strong>Edit</strong></p>
  
  <p>I've done some experimenting with structs and marshalling, after input from Spo1ler.</p>
  
  <p>Doing it this way, It's simple to serialize any message to a byte array</p>
  
  <pre><code>public interface IMsg
  {
      byte MessageId { get; }
      byte Length { get; }
  }
  
  [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
  public struct SetTime: IMsg
  {
      public byte Id { get; }
      [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
      public byte[] Time;
  
      public StartLoggerWithSampleInterval(byte time)
      {
          Id = (byte) MessageType.SetTime;
          Time = time;
      }
  }
  </code></pre>
  
  <p>I then have this static class to serialize the messages:</p>
  
  <pre><code>public static class MessageSerializer
  {
      public static byte[] Serialize(IMsg msg)
      {
          int size = Marshal.SizeOf(msg);
          byte[] serialized = new byte[size];
          IntPtr ptr = Marshal.AllocHGlobal(size);
  
          Marshal.StructureToPtr(msg, ptr, true);
          Marshal.Copy(ptr, serialized, 0, size);
          Marshal.FreeHGlobal(ptr);
  
          return serialized;
      }
  }
  </code></pre>
  
  <p>Initially this seems to be working like I want. Any problems that can show up doing it this way? </p>
  
  <p>However, the deserialization of the messages will be a pain to write, though the first byte in the message (MessageId) should tell me what type of struct the byte array translates to </p>