Differences
This shows you the differences between two versions of the page.
— | development:csharp:marshaling [2022/04/21 13:27] (current) – created - external edit 127.0.0.1 | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ====== C# Marshaling - write bytes to struct and vice versa ====== | ||
+ | <code c#> | ||
+ | [StructLayout(LayoutKind.Sequential, | ||
+ | public struct MyStructure | ||
+ | { | ||
+ | [MarshalAs(UnmanagedType.ByValArray, | ||
+ | public char[] Name; | ||
+ | public UInt16 Port; | ||
+ | public byte Num; | ||
+ | public byte Max; | ||
+ | public UInt64 Version; | ||
+ | public byte TOD; | ||
+ | public byte Avg; | ||
+ | public byte Flags; | ||
+ | [MarshalAs(UnmanagedType.ByValArray, | ||
+ | public char[] Key; | ||
+ | } | ||
+ | public static MyStructure BytesToMyStructure(Byte[] bytes) | ||
+ | { | ||
+ | MyStructure X = new(); | ||
+ | int size = Marshal.SizeOf(X); | ||
+ | IntPtr ptr = Marshal.AllocHGlobal(size); | ||
+ | Marshal.Copy(bytes, | ||
+ | X = (S.EnrollServer)Marshal.PtrToStructure(ptr, | ||
+ | Marshal.FreeHGlobal(ptr); | ||
+ | return X; | ||
+ | } | ||
+ | public static Byte[] MyStructureToBytes(MyStructure data) | ||
+ | { | ||
+ | int size = Marshal.SizeOf(data); | ||
+ | byte[] bytes = new byte[size]; | ||
+ | IntPtr ptr = Marshal.AllocHGlobal(size); | ||
+ | Marshal.StructureToPtr(data, | ||
+ | Marshal.Copy(ptr, | ||
+ | Marshal.FreeHGlobal(ptr); | ||
+ | return bytes; | ||
+ | } | ||
+ | </ | ||
+ | <code c# Generic method> | ||
+ | [StructLayout(LayoutKind.Sequential, | ||
+ | public class EnrollServer_Startup | ||
+ | { | ||
+ | public UInt16 Port; | ||
+ | [MarshalAs(UnmanagedType.ByValArray, | ||
+ | public char[] Name; | ||
+ | [MarshalAs(UnmanagedType.ByValArray, | ||
+ | public char[] Description; | ||
+ | [MarshalAs(UnmanagedType.ByValArray, | ||
+ | public char[] BannerUrl; | ||
+ | [MarshalAs(UnmanagedType.ByValArray, | ||
+ | public char[] Key; | ||
+ | public byte NumPlayers; | ||
+ | public byte MaxNumPlayers; | ||
+ | public UInt64 GameVersion; | ||
+ | public byte TimeOfDay; | ||
+ | public byte AverageFPS; | ||
+ | public byte Flags; // PasswordProtected | ||
+ | public byte Playstyle; | ||
+ | public UInt16 SpawnAmounts; | ||
+ | |||
+ | public static int SizeOf => Marshal.SizeOf(typeof(EnrollServer_Startup)); | ||
+ | public Byte[] ToBytes() | ||
+ | { | ||
+ | int size = Marshal.SizeOf(this); | ||
+ | byte[] bytes = new byte[size]; | ||
+ | IntPtr ptr = Marshal.AllocHGlobal(size); | ||
+ | Marshal.StructureToPtr(this, | ||
+ | Marshal.Copy(ptr, | ||
+ | Marshal.FreeHGlobal(ptr); | ||
+ | return bytes; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | public static T BytesToObject< | ||
+ | { | ||
+ | object X = Activator.CreateInstance(typeof(T))!; | ||
+ | int size = Marshal.SizeOf(X); | ||
+ | IntPtr ptr = Marshal.AllocHGlobal(size); | ||
+ | Marshal.Copy(bytes, | ||
+ | X = (T)Marshal.PtrToStructure(ptr, | ||
+ | Marshal.FreeHGlobal(ptr); | ||
+ | return (T)X; | ||
+ | } | ||
+ | </ |