C# 将结构体转为字节流的方式

1、 将基础类型转为byte数组存储

 1  private byte[] CreateNetDataByteStream(ushort system, ushort host, ushort type, byte[] tx_buf, ushort msg_len, ushort flag)
 2 
 3         {
 4 
 5             if (tx_buf == null)
 6 
 7             {
 8 
 9                 return null;
10 
11             }
12 
13             try
14 
15             {
16 
17                 byte[] data = new byte[msg_len + NetDataHeadLen];
18 
19                 byte[] u16byte = new byte[2];
20 
21                 u16byte = BitConverter.GetBytes(type);
22 
23                 Array.Copy(u16byte, 0, data, 0, 2);
24 
25                 u16byte = BitConverter.GetBytes(flag);
26 
27                 Array.Copy(u16byte, 0, data, 4, 2);
28 
29                 u16byte = BitConverter.GetBytes(msg_len);
30 
31                 Array.Copy(u16byte, 0, data, 2, 2);
32 
33                // u16byte = BitConverter.GetBytes(CommonConstant.MySystemID);
34 
35                 Array.Copy(u16byte, 0, data, 6, 2);
36 
37               //  u16byte = BitConverter.GetBytes((ushort)CommonConstant.MySeatName);
38 
39                 Array.Copy(u16byte, 0, data, 8, 2);
40 
41                 u16byte = BitConverter.GetBytes(system);
42 
43                 Array.Copy(u16byte, 0, data, 15, 2);
44 
45                 u16byte = BitConverter.GetBytes(host);
46 
47                 Array.Copy(u16byte, 0, data, 17, 2);
48 
49                 tx_buf.CopyTo(data, NetDataHeadLen);
50 
51                 return data;
52 
53             }
54 
55             catch
56 
57             {
58                 return null;
59 
60             }
61 
62         }

2.C#中结构体 与 字节流 相互转化

       

方式一
        //将一个结构序列化为字节数组
               private IFormatter formatter = new BinaryFormatter();
        private ValueType deserializeByteArrayToInfoObj(byte[] bytes)
        {
            ValueType vt;
            if (bytes == null || bytes.Length == 0)
            {
                return null;
            }

            try
            {
                MemoryStream stream = new MemoryStream(bytes);
                stream.Position = 0;
                stream.Seek(0, SeekOrigin.Begin);
                vt = (ValueType)formatter.Deserialize(stream);
                stream.Close();
                return vt;
            }
            catch (Exception ex)
            {
                return null;
            }
        }
        //将一个结构序列化为字节数组
        private byte[] serializeInfoObjToByteArray(ValueType infoStruct)
        {
            if (infoStruct == null)
            {
                return null;
            }

            try
            {
                MemoryStream stream = new MemoryStream();
                formatter.Serialize(stream, infoStruct);

                byte[] bytes = new byte[(int)stream.Length];
                stream.Position = 0;
                int count = stream.Read(bytes, 0, (int)stream.Length);
                stream.Close();
                return bytes;
            }
            catch (Exception ex)
            {
                return null;
            }
        }
方式二
   /// <summary>
        /// 将字节数组转换为结构体
        /// </summary>
        /// <param name="bytes"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public object ByteaToStruct(byte[] bytes, Type type)
        {
            //得到结构体大小
            int size = Marshal.SizeOf(type);
            Math.Log(size, 1);

            if (size > bytes.Length)
                return null;
            //分配结构大小的内存空间
            IntPtr structPtr = Marshal.AllocHGlobal(size);
            //将BYTE数组拷贝到分配好的内存空间
            Marshal.Copy(bytes, 0, structPtr, size);
            //将内存空间转换为目标结构
            object obj = Marshal.PtrToStructure(structPtr, type);
            //释放内容空间
            Marshal.FreeHGlobal(structPtr);
            return obj;
        }
        /// <summary>
        /// 将结构转换为字节数组
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public byte[] StructTOBytes(object obj)
        {
            int size = Marshal.SizeOf(obj);
            //创建byte数组
            byte[] bytes = new byte[size];
            IntPtr structPtr = Marshal.AllocHGlobal(size);
            //将结构体拷贝到分配好的内存空间
            Marshal.StructureToPtr(obj, structPtr, false);
            //从内存空间拷贝到byte数组
            Marshal.Copy(structPtr, bytes,0, size);
            //释放内存空间
            Marshal.FreeHGlobal(structPtr);
            return bytes;
        }

3. C# 结构体字节对齐

1 [structLayout(Layoutkind.sequential,charset=charset.ansi)]
2 Struct Mystruct
3 {
4 [MarshalAs(UnmanagedType.ByValArray,sizeConst=8)]
5 Public byte[] serial;
6 Public byte Type;
7 Public uint Sum;
8 }

在上述结构体与字节流转换第二种方法中,获取结构体长度int size = Marshal.SizeOf(Mystruct);,并不是13,而是16。在内存特定类型数据结构起始地址通常有一定的对齐要求,比如32位机器的int起始地址必须是4的整数倍,结构通常也如此

需要添加[structLayout(Layoutkind.sequential,charset=charset.ansi,pack=1)]

posted @ 2016-09-05 12:54  九园  阅读(5316)  评论(0编辑  收藏  举报