C# 通訊時字節流和結構體互轉
//轉換C#代碼://結構體轉換成字節流
public static byte[] StructToBytes<T>(T obj) { int size = Marshal.SizeOf(typeof(T)); IntPtr bufferPtr = Marshal.AllocHGlobal(size); try
{ Marshal.StructureToPtr(obj, bufferPtr, false); byte[] bytes = new byte[size]; Marshal.Copy(bufferPtr, bytes, 0, size);return bytes;
} catch(Exception ex) { throw new Exception("Error in StructToBytes ! " + ex.Message); } finally
{
Marshal.FreeHGlobal(bufferPtr);
}
}//字節流轉換成結構體
public static T BytesToStruct<T>(byte[] bytes, int startIndex = 0) { if (bytes == null) return default(T); if (bytes.Length <= 0) return default(T);
int objLength = Marshal.SizeOf(typeof(T)); IntPtr bufferPtr = Marshal.AllocHGlobal(objLength); try//struct_bytes轉換 { Marshal.Copy(bytes, startIndex, bufferPtr, objLength); return (T)Marshal.PtrToStructure(bufferPtr, typeof(T)); } catch(Exception ex) { throw new Exception("Error in BytesToStruct ! " + ex.Message); } finally { Marshal.FreeHGlobal(bufferPtr); } }
[StructLayout(LayoutKind.Sequential, Pack=1)] //變量在內存中的對齊方式 public struct LolMsgHeader { public ushort wMsgLen; public byte header_ver; public ushort uAction; //動作行為 public uint dwUid; //用戶ID public uint dwSeq; //包的序列號 public uint dwPid; //當前服務ID
};
public struct LOLMoveMsg { [MarshalAs(UnmanagedType.SysUInt, SizeConst = LOLMsgConst.MASK_LEN)] public WORD mask; // 掩碼 [MarshalAs(UnmanagedType.ByValArray, SizeConst = LOLMsgConst.NAME_LEN)] public byte[] szName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = LOLMsgConst.NAME_LEN)] public string targetName; //目的對象 public short x; public short y; public byte byReached; //到達目的地,未到達0,到達1 };
//注意,之前遇到過在ios真機上運行不起來的bug,在android真機和ios模擬器上都是OK的問題,
后來把所有的ByValArray改成ByValTStr解決了這個問題。
如果有可能,建議不要用數組,全部都用基本類型。</pre>