你的位置:首页 > ASP.net教程

[ASP.net教程]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       try14 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       catch56 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 Mystruct3 {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)]