using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.InteropServices; namespace Aitex.Core.Util { public class ByteStructConverter { public static T ToStruct(byte[] by) where T : struct { int objectSize = Marshal.SizeOf(typeof(T)); if (objectSize > by.Length) return default(T); // Allocate some unmanaged memory. IntPtr buffer = Marshal.AllocHGlobal(objectSize); // Copy the read byte array (byte[]) into the unmanaged memory block. Marshal.Copy(by, 0, buffer, objectSize); // Push the memory into a new struct of type (T). T returnStruct = (T)Marshal.PtrToStructure(buffer, typeof(T)); // Free the unmanaged memory block. Marshal.FreeHGlobal(buffer); return returnStruct; } public static object ToStruct(byte[] buffer, Type t) { int objectSize = Marshal.SizeOf(t); if (objectSize > buffer.Length) return null; // Allocate some unmanaged memory. IntPtr buf = Marshal.AllocHGlobal(objectSize); // Copy the read byte array (byte[]) into the unmanaged memory block. Marshal.Copy(buffer, 0, buf, objectSize); // Push the memory into a new struct of type (T). object result = Marshal.PtrToStructure(buf, t); // Free the unmanaged memory block. Marshal.FreeHGlobal(buf); return result; } public static byte[] Struct2Bytes(object o) { // create a new byte buffer the size of your struct byte[] buffer = new byte[Marshal.SizeOf(o)]; // pin the buffer so we can copy data into it w/o GC collecting it GCHandle bufferHandle = GCHandle.Alloc(buffer, GCHandleType.Pinned); // copy the struct data into the buffer Marshal.StructureToPtr(o, bufferHandle.AddrOfPinnedObject(), false); // free the GC handle bufferHandle.Free(); return buffer; } } }