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)]