using System; using System.Runtime.InteropServices; namespace WinDll.Utils { ///*************************************** /// The Maybe datatype ///*************************************** public enum ListMaybe { cMaybeNothing, cMaybeJust }; [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct Nothing { }; [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public unsafe struct Just { public void* maybe_just_var1; }; [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)] public struct MaybeUnion { [FieldOffset(0)] public Nothing nothing; [FieldOffset(0)] public Just just; }; [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public unsafe struct Maybe { public ListMaybe tag; public MaybeUnion* elt; }; public unsafe partial class FFI { [DllImport("msvcrt.dll",CallingConvention=CallingConvention.Cdecl,EntryPoint="_msize")] public unsafe static extern uint _msize(void* obj); [DllImport("msvcrt.dll",CallingConvention=CallingConvention.Cdecl,EntryPoint="free", SetLastError =true)] private unsafe static extern void freeNative(void* obj); public unsafe static void free(void* obj) { if (obj == null) return; freeNative(obj); obj = null; } public static void free(IntPtr ptr) { if (ptr != IntPtr.Zero) free(ptr.ToPointer()); } public static unsafe void freeTuple(Tuples.Tuple3* tuple3) { if (tuple3 == null) return; FFI.free(tuple3->tuple3_var1); FFI.free(tuple3->tuple3_var2); FFI.free(tuple3->tuple3_var3); FFI.free(tuple3); tuple3 = null; } public static unsafe void freeTuple(Tuples.Tuple2* tuple2) { if (tuple2 == null) return; FFI.free(tuple2->tuple2_var1); FFI.free(tuple2->tuple2_var2); FFI.free(tuple2); tuple2 = null; } public static unsafe void* readMaybe(Maybe* value) { void* val = null; switch (value->tag) { case ListMaybe.cMaybeNothing: break; case ListMaybe.cMaybeJust: val = value->elt->just.maybe_just_var1; break; default: break; } free(value->elt); free(value); return val; } /// /// In an indexed tuple the first element is a normal integer and not a pointer, so we shouldn't try to free it. /// /// public static unsafe void freeIndexTuple(Tuples.Tuple2* tuple2) { if (tuple2 == null) return; FFI.free(tuple2->tuple2_var2); FFI.free(tuple2); tuple2 = null; } } public unsafe class Tuples { ///*************************************** /// The Tuple datatypes ///*************************************** [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct Tuple2 { public void* tuple2_var1; public void* tuple2_var2; }; [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct Tuple3 { public void* tuple3_var1; public void* tuple3_var2; public void* tuple3_var3; }; [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct Tuple4 { public void* tuple4_var1; public void* tuple4_var2; public void* tuple4_var3; public void* tuple4_var4; }; [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct Tuple5 { public void* tuple5_var1; public void* tuple5_var2; public void* tuple5_var3; public void* tuple5_var4; public void* tuple5_var5; }; [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct Tuple6 { public void* tuple6_var1; public void* tuple6_var2; public void* tuple6_var3; public void* tuple6_var4; public void* tuple6_var5; public void* tuple6_var6; }; [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct Tuple7 { public void* tuple7_var1; public void* tuple7_var2; public void* tuple7_var3; public void* tuple7_var4; public void* tuple7_var5; public void* tuple7_var6; public void* tuple7_var7; }; [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct Tuple8 { public void* tuple8_var1; public void* tuple8_var2; public void* tuple8_var3; public void* tuple8_var4; public void* tuple8_var5; public void* tuple8_var6; public void* tuple8_var7; public void* tuple8_var8; }; } }