0

I have an object I'd like to serialize to a memory buffer, which is then sent via UART to an embedded device. I'm working in a C# environment on windows.

What I'd like to do is to create two classes that look like this:

class StatusElement
{
    byte statusPart1;
    byte statusPart2;
}

class DeviceCommand
{
    byte Address;
    byte Length;
    StatusElement[] statusElements; // Can have an arbitrary number of elements in it
}

I'd like to use a serialize, preferably something based on c# serialization, to convert the second class to a byte stream.

The problem is that the embedded device is hard-coded to accept an exact sequence (AddressByte, LengthByte .... ErrorCorrectionByte) so I cannot use the regular C# serialization, which adds serialization metadata in the stream. This also rules out other serializes like Protobuf.

So my question is: Is it possible to customize the c# serialization to get the output I need? How?

--- Update ---

Thanks everyone for the help. After consideration I’ve decided to implement my own mini-serializer, using reflection and per-type handler. More complex but gives me more flexibility and automation capabilities.

Shay Shilo
  • 11
  • 2
  • 1
    you should just write your own. – Daniel A. White Aug 12 '12 at 13:27
  • Yes, write custom logic that you can use to serialize your classes into suitable byte streams. – A Person Aug 12 '12 at 13:30
  • Check out [protobuf-csharp-port](http://code.google.com/p/protobuf-csharp-port/) – Chris Gessler Aug 12 '12 at 13:44
  • BinaryReader/Writer is best. You could hack something like this: http://stackoverflow.com/a/1936208/17034 – Hans Passant Aug 12 '12 at 13:54
  • If I understand correctly, something similar happens under the hood when calling a native library with a struct with `LayoutKind.Sequential`. Maybe you could use that somehow, to avoid writing the serialization yourself. See here for a starting point: http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.structlayoutattribute.aspx – Tim S. Aug 12 '12 at 13:56

2 Answers2

1

use a MemoryStream to manully serialize your object.

private byte[] Serialize()
{
    using (var ms = new MemoryStream())
    {
        ms.WriteByte(Address);
        ms.WriteByte(Length);
        foreach (var element in statusElements)
        {
            ms.WriteByte(element.statusPart1);
            ms.WriteByte(element.statusPart2);
        }
        return ms.ToArray();
    }
}

Likewise for deserialization:

private static DeviceCommand Deserialize(byte[] input)
{
    DeviceCommand result = new DeviceCommand();
    using (var ms = new MemoryStream(input))
    {
        result.Address = ms.ReadByte();
        result.Length = ms.ReadByte();

        //assuming .Length contains the number of statusElements:
        result.statusElemetns = new StatusElement[result.Length];
        for (int i = 0; i < result.Length; i++)
        {
            result.statusElements[i] = new StatusElement();
            result.statusElements[i].statusPart1 = ms.ReadByte();
            result.statusElements[i].statusPart2 = ms.ReadByte();
        }
    }
    return result;
}
Rotem
  • 21,452
  • 6
  • 62
  • 109
0

If you need only to write bytes or byte arrays, you can use the MemoryStream directly. If you want to use other .NET base types, access your Stream with a System.IO.BinaryWriter / BinaryReader. This class is used by the System.Runtime.Serialization.Formatters.Binary.BinaryFormatter for binary serialization and deserialization.