1

I am writing my custom serializer for my class which should serialize a class object to a byte array. Below is my sample code:

[StructLayout(LayoutKind.Sequential)]
public class ATTRIBUTE_STR
{
    public uint atType;
    public uint atLen;
    public byte[] atData = new byte[3];

    public byte[] serialize()
    {
        byte[] temp = new byte[Marshal.SizeOf(this)];

        byte[] buffer = BitConverter.GetBytes(atType);
        Array.Copy(buffer, 0, temp, 0, buffer.Length);

        buffer = null;
        buffer = BitConverter.GetBytes(atLen);
        Array.Copy(buffer, 0, temp, 4, buffer.Length);

        Array.Copy(this.atData, 0, temp, 8, this.atData.Length);

        return temp;

    }

};

However, the byte array atData because of how its stored in memory with byte alignment and all, it's not getting correctly into the temp byte array. Since the byte arrays have even byte alignment.

How can I serialize this object accounting for the alignment of members in memory?

EDIT: I know there are other options like Marshalling or ProtocolBuffers, but I would like using my custom serializer.

5
  • Did you mean to use a struct and not a class? You can get the struct offset in unmanaged memory by Marshal.OffsetOf() Commented Nov 26, 2013 at 16:15
  • No, I meant a class only. Commented Nov 26, 2013 at 16:21
  • "i think it's not being rightly copied into the byte array." - can you explain your actual problem? Commented Nov 26, 2013 at 16:25
  • I have edited it in the question Commented Nov 26, 2013 at 16:38
  • You changed "not right" to "not correctly" which is hardly helpful. Show what you expect to be in the array and what is actually in there. Commented Nov 27, 2013 at 7:07

1 Answer 1

1

Your sizeof call is probably not returning what you think it is, but there hardly seems much point worrying about Sizeof if you're going to stick with hard-coded offsets for the output.]

So you might as well do something like this:

byte[] temp = new byte[8+atLen.Length];
BitConverter.GetBytes(atType).CopyTo(temp,0);
BitConverter.GetBytes(atLen).CopyTo(temp,4);
this.AtData.CopyTo(temp,8);
return temp;

Update: Sizeof returns the amount of unmanaged space necessary to store your object - but bear in mind that your atData array contents are not stored within your object, they are in an array object which is referred to by your object. So Marshal.Sizeof is not going to give you an answer which includes the size of your array - indeed, if you ask Marshal.Sizeof to give you Sizeof(atData), you'll get an exception.

Sign up to request clarification or add additional context in comments.

3 Comments

Marshal.SizeOf() returns size including alignments which is why its not just sum of sizeof mem1, mem2 and mem3. Array.CopyTo accounts for mem alignment? If it does, then temp doesn't have enough space to store AtData right
It would be better if I can use a sizeof instead of hard coded values
CopyTo is just an array copy, it doesn't know anything about alignment/padding. Do you know what the specific alignment/padding requirements at the receiving end are?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.