none
How do I marshal an array of fixed length data structures to a byte array? RRS feed

  • Question

  • I am writing a custom binary serializer and I'd like to convert from an array of fixed length data structures to a byte[]. I want the serializer to be generic and not need to understand the structure type. Here's an example of one possible structure definition:

    [Serializable, StructLayout(LayoutKind.Sequential)]
    publicstruct DataPoint
    {
         float A{ get; set; }
         float B{ get; set; }
         float C{ get; set; }
    }

    Here's my first attempt at the serializer but I can't seem to figure out the array length from the object reference to the array:

    // 'value' is a reference to a structure array (eg. DataPoint[])
    public byte[] SerializeArray(object value)
    {
       Type type = value.GetType();
       Type etype = type.GetElementType();
       int esize = Marshal.SizeOf(etype);
       // I was hoping this would return the array length, but it throws
       int size = Marshal.SizeOf(value);    
       IntPtr ptr = Marshal.AllocHGlobal(esize*size);
       Marshal.StructureToPtr(value, ptr, false);      
       byte[] bytes = new byte[esize * size];
       Marshal.Copy(ptr, bytes, 0, esize * size);
       Marshal.FreeHGlobal(ptr);
    }

    Thanks,

    Aaron


    Friday, January 15, 2016 7:50 PM

Answers

  • In order to get the size of 1D array, try this:

        Array arr = (Array)value;

        int size = arr.Length;

    Or change the type of value to Array.

    I think that StructureToPtr should be applied for each item separately:

        IntPtr ptr = Marshal.AllocHGlobal( esize * size );

        IntPtr d = ptr;

        for( int i = 0; i < size; ++i )

        {

            Marshal.StructureToPtr( arr.GetValue( i ), d, false );

            d += esize;

        }

    Another solution probably can be based on pointers and fixed keyword.

    Friday, January 15, 2016 9:08 PM