Byte for byte serialization of a struct in C#

前端 未结 4 1133
长情又很酷
长情又很酷 2020-11-30 06:26

I\'m looking for language support of serialization in C#. I could derive from ISerializable and implement the serialization by copying member values in a byte buffer. Howeve

4条回答
  •  南笙
    南笙 (楼主)
    2020-11-30 06:48

    Just use this two methods:

    public static class StructTools
    {
        /// 
        /// converts byte[] to struct
        /// 
        public static T RawDeserialize(byte[] rawData, int position)
        {
            int rawsize = Marshal.SizeOf(typeof(T));
            if (rawsize > rawData.Length - position)
                throw new ArgumentException("Not enough data to fill struct. Array length from position: "+(rawData.Length-position) + ", Struct length: "+rawsize);
            IntPtr buffer = Marshal.AllocHGlobal(rawsize);
            Marshal.Copy(rawData, position, buffer, rawsize);
            T retobj = (T)Marshal.PtrToStructure(buffer, typeof(T));
            Marshal.FreeHGlobal(buffer);
            return retobj;
        }
    
        /// 
        /// converts a struct to byte[]
        /// 
        public static byte[] RawSerialize(object anything)
        {
            int rawSize = Marshal.SizeOf(anything);
            IntPtr buffer = Marshal.AllocHGlobal(rawSize);
            Marshal.StructureToPtr(anything, buffer, false);
            byte[] rawDatas = new byte[rawSize];
            Marshal.Copy(buffer, rawDatas, 0, rawSize);
            Marshal.FreeHGlobal(buffer);
            return rawDatas;
        }
    }
    

    And specify your struct like this (Specify the exact size and pack (align) by one byte. default is 8):

    [StructLayout(LayoutKind.Explicit, Size = 11, Pack = 1)]
    private struct MyStructType
    {
        [FieldOffset(0)]
        public UInt16 Type;
        [FieldOffset(2)]
        public Byte DeviceNumber;
        [FieldOffset(3)]
        public UInt32 TableVersion;
        [FieldOffset(7)]
        public UInt32 SerialNumber;
    }
    

    Now you can Deserialize using

    StructTools.RawDeserialize(byteArray, 0); // 0 is offset in byte[]
    

    and serialize using

    StructTools.RawSerialize(myStruct);
    

提交回复
热议问题