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; } }
方式二 ////// 将字节数组转换为结构体 /// /// /// /// 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; } /// /// 将结构转换为字节数组 /// /// /// 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)]