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; | ||
| + | } | ||
| + | </ | ||