ByteStructConverter.cs 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Runtime.InteropServices;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. namespace EPD.Data
  8. {
  9. public class ByteStructConverter
  10. {
  11. public static T ToStruct<T>(byte[] by) where T : struct
  12. {
  13. int objectSize = Marshal.SizeOf(typeof(T));
  14. if (objectSize > by.Length) return default(T);
  15. // Allocate some unmanaged memory.
  16. IntPtr buffer = Marshal.AllocHGlobal(objectSize);
  17. // Copy the read byte array (byte[]) into the unmanaged memory block.
  18. Marshal.Copy(by, 0, buffer, objectSize);
  19. // Push the memory into a new struct of type (T).
  20. T returnStruct = (T)Marshal.PtrToStructure(buffer, typeof(T));
  21. // Free the unmanaged memory block.
  22. Marshal.FreeHGlobal(buffer);
  23. return returnStruct;
  24. }
  25. public static object ToStruct(byte[] buffer, Type t)
  26. {
  27. int objectSize = Marshal.SizeOf(t);
  28. if (objectSize > buffer.Length) return null;
  29. // Allocate some unmanaged memory.
  30. IntPtr buf = Marshal.AllocHGlobal(objectSize);
  31. // Copy the read byte array (byte[]) into the unmanaged memory block.
  32. Marshal.Copy(buffer, 0, buf, objectSize);
  33. // Push the memory into a new struct of type (T).
  34. object result = Marshal.PtrToStructure(buf, t);
  35. // Free the unmanaged memory block.
  36. Marshal.FreeHGlobal(buf);
  37. return result;
  38. }
  39. public static byte[] Struct2Bytes(object o)
  40. {
  41. // create a new byte buffer the size of your struct
  42. byte[] buffer = new byte[Marshal.SizeOf(o)];
  43. // pin the buffer so we can copy data into it w/o GC collecting it
  44. GCHandle bufferHandle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
  45. // copy the struct data into the buffer
  46. Marshal.StructureToPtr(o, bufferHandle.AddrOfPinnedObject(), false);
  47. // free the GC handle
  48. bufferHandle.Free();
  49. return buffer;
  50. }
  51. }
  52. }