1 #pragma warning disable 1591
5 using System.Runtime.InteropServices;
6 using System.Collections.Generic;
7 using System.Reflection;
10 using static Eina.HashNativeFunctions;
11 using static Eina.InarrayNativeFunctions;
12 using static Eina.InlistNativeFunctions;
13 using static Eina.NativeCustomExportFunctions;
18 public enum ElementType
26 [StructLayout(LayoutKind.Sequential)]
27 public struct InlistMem
29 public IntPtr next {get;set;}
30 public IntPtr prev {get;set;}
31 public IntPtr last {get;set;}
34 [StructLayout(LayoutKind.Sequential)]
35 public struct InlistNode<T>
37 public InlistMem __in_list {get;set;}
38 public T Val {get;set;}
41 public interface IBaseElementTraits<T>
43 IntPtr ManagedToNativeAlloc(T man);
44 IntPtr ManagedToNativeAllocInlistNode(T man);
45 void ManagedToNativeCopyTo(T man, IntPtr mem);
46 void NativeFree(IntPtr nat);
47 void NativeFreeInlistNodeElement(IntPtr nat);
48 void NativeFreeInlistNode(IntPtr nat, bool freeElement);
49 void NativeFreeInplace(IntPtr nat);
50 void ResidueFreeInplace(IntPtr nat);
51 T NativeToManaged(IntPtr nat);
52 T NativeToManagedInlistNode(IntPtr nat);
53 T NativeToManagedInplace(IntPtr nat);
54 IntPtr EinaCompareCb();
57 IntPtr EinaInarrayNew(uint step);
58 IntPtr EinaHashIteratorKeyNew(IntPtr hash);
61 public class StringElementTraits : IBaseElementTraits<string>
63 public StringElementTraits()
67 public IntPtr ManagedToNativeAlloc(string man)
69 IntPtr newstring = MemoryNative.StrDup(man);
73 public IntPtr ManagedToNativeAllocInlistNode(string man)
75 var node = new InlistNode<IntPtr>();
76 node.Val = ManagedToNativeAlloc(man);
77 GCHandle pinnedData = GCHandle.Alloc(node, GCHandleType.Pinned);
78 IntPtr ptr = pinnedData.AddrOfPinnedObject();
79 IntPtr nat = MemoryNative.AllocCopy(ptr, Marshal.SizeOf<InlistMem>() + Marshal.SizeOf<IntPtr>());
84 public void ManagedToNativeCopyTo(string man, IntPtr mem)
86 IntPtr stringptr = ManagedToNativeAlloc(man);
87 Marshal.WriteIntPtr(mem, stringptr);
90 public void NativeFree(IntPtr nat)
92 if (nat != IntPtr.Zero)
94 MemoryNative.Free(nat);
98 public void NativeFreeInlistNodeElement(IntPtr nat)
100 if (nat == IntPtr.Zero)
105 var val = Marshal.PtrToStructure<IntPtr>
106 (nat + Marshal.SizeOf<InlistMem>());
110 public void NativeFreeInlistNode(IntPtr nat, bool freeElement)
112 if (nat == IntPtr.Zero)
119 NativeFreeInlistNodeElement(nat);
122 MemoryNative.Free(nat);
125 public void NativeFreeInplace(IntPtr nat)
127 MemoryNative.FreeRef(nat);
130 public void ResidueFreeInplace(IntPtr nat)
134 public string NativeToManaged(IntPtr nat)
136 if (nat == IntPtr.Zero)
138 return default(string);
141 return StringConversion.NativeUtf8ToManagedString(nat);
144 public string NativeToManagedInlistNode(IntPtr nat)
146 if (nat == IntPtr.Zero)
148 Eina.Log.Error("Null pointer for Inlist node.");
149 return default(string);
152 IntPtr ptr_location = nat + Marshal.SizeOf<InlistMem>();
153 return NativeToManaged(Marshal.ReadIntPtr(ptr_location));
156 // Strings inplaced are always a pointer, because they are variable-sized
157 public string NativeToManagedInplace(IntPtr nat)
159 if (nat == IntPtr.Zero)
161 return default(string);
164 nat = Marshal.ReadIntPtr(nat);
165 if (nat == IntPtr.Zero)
167 return default(string);
170 return NativeToManaged(nat);
173 public IntPtr EinaCompareCb()
175 return MemoryNative.StrCompareFuncPtrGet();
178 public IntPtr EinaFreeCb()
180 return MemoryNative.FreeFuncPtrGet();
183 public IntPtr EinaHashNew()
185 return eina_hash_string_superfast_new(IntPtr.Zero);
188 public IntPtr EinaInarrayNew(uint step)
190 return eina_inarray_new((uint)Marshal.SizeOf<IntPtr>(), step);
193 public IntPtr EinaHashIteratorKeyNew(IntPtr hash)
195 return eina_hash_iterator_key_new(hash);
199 public class StringshareElementTraits : IBaseElementTraits<Eina.Stringshare>
201 public StringshareElementTraits()
205 public IntPtr ManagedToNativeAlloc(Eina.Stringshare man)
207 var strShare = MemoryNative.AddStringshare(man);
211 public IntPtr ManagedToNativeAllocInlistNode(Eina.Stringshare man)
213 var node = new InlistNode<IntPtr>();
214 node.Val = ManagedToNativeAlloc(man);
215 GCHandle pinnedData = GCHandle.Alloc(node, GCHandleType.Pinned);
216 IntPtr ptr = pinnedData.AddrOfPinnedObject();
217 IntPtr nat = MemoryNative.AllocCopy
218 (ptr, Marshal.SizeOf<InlistMem>() + Marshal.SizeOf<IntPtr>());
223 public void ManagedToNativeCopyTo(Eina.Stringshare man, IntPtr mem)
225 IntPtr stringptr = ManagedToNativeAlloc(man);
226 Marshal.WriteIntPtr(mem, stringptr);
229 public void NativeFree(IntPtr nat)
231 if (nat != IntPtr.Zero)
233 MemoryNative.DelStringshare(nat);
237 public void NativeFreeInlistNodeElement(IntPtr nat)
239 if (nat == IntPtr.Zero)
244 var val = Marshal.PtrToStructure<IntPtr>
245 (nat + Marshal.SizeOf<InlistMem>());
249 public void NativeFreeInlistNode(IntPtr nat, bool freeElement)
251 if (nat == IntPtr.Zero)
258 NativeFreeInlistNodeElement(nat);
261 MemoryNative.Free(nat);
264 public void NativeFreeInplace(IntPtr nat)
266 MemoryNative.DelStringshareRef(nat);
269 public void ResidueFreeInplace(IntPtr nat)
273 public Eina.Stringshare NativeToManaged(IntPtr nat)
275 if (nat == IntPtr.Zero)
277 return default(Eina.Stringshare);
280 return StringConversion.NativeUtf8ToManagedString(nat);
283 public Eina.Stringshare NativeToManagedInlistNode(IntPtr nat)
285 if (nat == IntPtr.Zero)
287 Eina.Log.Error("Null pointer for Inlist node.");
288 return default(Eina.Stringshare);
291 IntPtr ptr_location = nat + Marshal.SizeOf<InlistMem>();
292 return NativeToManaged(Marshal.ReadIntPtr(ptr_location));
295 // Strings inplaced are always a pointer, because they are variable-sized
296 public Eina.Stringshare NativeToManagedInplace(IntPtr nat)
298 if (nat == IntPtr.Zero)
300 return default(Eina.Stringshare);
303 nat = Marshal.ReadIntPtr(nat);
304 if (nat == IntPtr.Zero)
306 return default(Eina.Stringshare);
309 return NativeToManaged(nat);
312 public IntPtr EinaCompareCb()
314 return MemoryNative.StrCompareFuncPtrGet();
317 public IntPtr EinaFreeCb()
319 return MemoryNative.StringshareDelFuncPtrGet();
322 public IntPtr EinaHashNew()
324 return eina_hash_stringshared_new(MemoryNative.StringshareDelFuncPtrGet());
327 public IntPtr EinaInarrayNew(uint step)
329 return eina_inarray_new((uint)Marshal.SizeOf<IntPtr>(), step);
332 public IntPtr EinaHashIteratorKeyNew(IntPtr hash)
334 return eina_hash_iterator_key_new(hash);
338 public class EflObjectElementTraits<T> : IBaseElementTraits<T>
340 public IntPtr ManagedToNativeAlloc(T man)
342 IntPtr h = ((Efl.Eo.IWrapper)man).NativeHandle;
343 if (h == IntPtr.Zero)
348 return Efl.Eo.Globals.efl_ref(h);
351 public IntPtr ManagedToNativeAllocInlistNode(T man)
353 var node = new InlistNode<IntPtr>();
354 node.Val = ManagedToNativeAlloc(man);
355 GCHandle pinnedData = GCHandle.Alloc(node, GCHandleType.Pinned);
356 IntPtr ptr = pinnedData.AddrOfPinnedObject();
357 IntPtr nat = MemoryNative.AllocCopy(ptr, Marshal.SizeOf<InlistMem>() + Marshal.SizeOf<IntPtr>());
362 public void ManagedToNativeCopyTo(T man, IntPtr mem)
364 IntPtr v = ManagedToNativeAlloc(man);
365 Marshal.WriteIntPtr(mem, v);
368 public void NativeFree(IntPtr nat)
370 if (nat != IntPtr.Zero)
372 Efl.Eo.Globals.efl_mono_thread_safe_efl_unref(nat);
376 public void NativeFreeRef(IntPtr nat, bool unrefs)
384 public void NativeFreeInlistNodeElement(IntPtr nat)
386 if (nat == IntPtr.Zero)
391 var val = Marshal.PtrToStructure<IntPtr>
392 (nat + Marshal.SizeOf<InlistMem>());
396 public void NativeFreeInlistNode(IntPtr nat, bool freeElement)
398 if (nat == IntPtr.Zero)
405 NativeFreeInlistNodeElement(nat);
408 MemoryNative.Free(nat);
411 public void NativeFreeInplace(IntPtr nat)
416 public void ResidueFreeInplace(IntPtr nat)
420 public T NativeToManaged(IntPtr nat)
422 if (nat == IntPtr.Zero)
427 return (T) Efl.Eo.Globals.CreateWrapperFor(nat, shouldIncRef: true);
430 public T NativeToManagedRef(IntPtr nat)
432 if (nat == IntPtr.Zero)
437 return NativeToManaged(nat);
440 public T NativeToManagedInlistNode(IntPtr nat)
442 if (nat == IntPtr.Zero)
444 Eina.Log.Error("Null pointer for Inlist node.");
448 IntPtr ptr_location = nat + Marshal.SizeOf<InlistMem>();
449 return NativeToManaged(Marshal.ReadIntPtr(ptr_location));
452 // EFL objects inplaced are always a pointer, because they are variable-sized
453 public T NativeToManagedInplace(IntPtr nat)
455 if (nat == IntPtr.Zero)
460 nat = Marshal.ReadIntPtr(nat);
461 if (nat == IntPtr.Zero)
466 return NativeToManaged(nat);
469 public IntPtr EinaCompareCb()
471 return MemoryNative.PtrCompareFuncPtrGet();
474 public IntPtr EinaFreeCb()
476 return MemoryNative.EflUnrefFuncPtrGet();
479 public IntPtr EinaHashNew()
481 return eina_hash_pointer_new(IntPtr.Zero);
484 public IntPtr EinaInarrayNew(uint step)
486 return eina_inarray_new((uint)Marshal.SizeOf<IntPtr>(), step);
489 public IntPtr EinaHashIteratorKeyNew(IntPtr hash)
491 return eina_hash_iterator_ptr_key_wrapper_new_custom_export_mono(hash);
495 public abstract class PrimitiveElementTraits<T>
497 private Eina_Compare_Cb dlgt = null;
499 public IntPtr ManagedToNativeAlloc(T man)
501 return PrimitiveConversion.ManagedToPointerAlloc(man);
504 public IntPtr ManagedToNativeAllocInlistNode(T man)
506 var node = new InlistNode<T>();
508 GCHandle pinnedData = GCHandle.Alloc(node, GCHandleType.Pinned);
509 IntPtr ptr = pinnedData.AddrOfPinnedObject();
510 int Tsize = Marshal.SizeOf<T>() < Marshal.SizeOf<IntPtr>() ? Marshal.SizeOf<IntPtr>() : Marshal.SizeOf<T>();
511 IntPtr nat = MemoryNative.AllocCopy(ptr, Marshal.SizeOf<InlistMem>() + Tsize);
516 public void NativeFree(IntPtr nat)
518 MemoryNative.Free(nat);
521 public void NativeFreeInlistNodeElement(IntPtr nat)
526 public void NativeFreeInlistNode(IntPtr nat, bool freeElement)
528 MemoryNative.Free(nat);
531 public void NativeFreeInplace(IntPtr nat)
536 public void ResidueFreeInplace(IntPtr nat)
541 public T NativeToManaged(IntPtr nat)
543 if (nat == IntPtr.Zero)
545 Eina.Log.Error("Null pointer on primitive/struct container.");
549 return PrimitiveConversion.PointerToManaged<T>(nat);
552 public T NativeToManagedRef(IntPtr nat)
554 return NativeToManaged(nat);
558 public T NativeToManagedInplace(IntPtr nat)
560 return NativeToManaged(nat);
563 private int PrimitiveCompareCb(IntPtr ptr1, IntPtr ptr2)
565 var m1 = (IComparable)NativeToManaged(ptr1);
566 var m2 = NativeToManaged(ptr2);
567 return m1.CompareTo(m2);
570 public IntPtr EinaCompareCb()
574 dlgt = new Eina_Compare_Cb(PrimitiveCompareCb);
577 return Marshal.GetFunctionPointerForDelegate(dlgt);
580 public IntPtr EinaFreeCb()
582 return MemoryNative.FreeFuncPtrGet();
585 public IntPtr EinaInarrayNew(uint step)
587 return eina_inarray_new((uint)Marshal.SizeOf<T>(), step);
590 public IntPtr EinaHashIteratorKeyNew(IntPtr hash)
592 return eina_hash_iterator_key_new(hash);
596 abstract public class Primitive32ElementTraits<T> : PrimitiveElementTraits<T>, IBaseElementTraits<T>
598 private static IBaseElementTraits<Int32> int32Traits = null;
600 public Primitive32ElementTraits()
602 if (int32Traits == null)
604 if (typeof(T) == typeof(Int32)) // avoid infinite recursion
606 int32Traits = (IBaseElementTraits<Int32>)this;
610 int32Traits = TraitFunctions.GetTypeTraits<Int32>();
615 public abstract void ManagedToNativeCopyTo(T man, IntPtr mem);
616 public abstract T NativeToManagedInlistNode(IntPtr nat);
618 public IntPtr ManagedToNativeAllocRef(T man, bool refs)
620 return int32Traits.ManagedToNativeAlloc(Convert.ToInt32((object)man));
623 public void NativeFreeRef(IntPtr nat, bool unrefs)
625 int32Traits.NativeFree(nat);
628 public IntPtr EinaHashNew()
630 return eina_hash_int32_new(IntPtr.Zero);
634 abstract public class Primitive64ElementTraits<T> : PrimitiveElementTraits<T>, IBaseElementTraits<T>
636 private static IBaseElementTraits<Int64> int64Traits = null;
638 public Primitive64ElementTraits()
640 if (int64Traits == null)
642 if (typeof(T) == typeof(Int64)) // avoid infinite recursion
644 int64Traits = (IBaseElementTraits<Int64>)this;
648 int64Traits = TraitFunctions.GetTypeTraits<Int64>();
653 public abstract void ManagedToNativeCopyTo(T man, IntPtr mem);
654 public abstract T NativeToManagedInlistNode(IntPtr nat);
656 public IntPtr ManagedToNativeAllocRef(T man, bool refs)
658 return int64Traits.ManagedToNativeAlloc(Convert.ToInt64((object)man));
661 public void NativeFreeRef(IntPtr nat, bool unrefs)
663 int64Traits.NativeFree(nat);
666 public IntPtr EinaHashNew()
668 return eina_hash_int64_new(IntPtr.Zero);
672 public class IntElementTraits : Primitive32ElementTraits<int>, IBaseElementTraits<int>
674 override public void ManagedToNativeCopyTo(int man, IntPtr mem)
676 var arr = new int[1];
678 Marshal.Copy(arr, 0, mem, 1);
681 override public int NativeToManagedInlistNode(IntPtr nat)
683 if (nat == IntPtr.Zero)
685 Eina.Log.Error("Null pointer for Inlist node.");
689 IntPtr loc = nat + Marshal.SizeOf<InlistMem>();
691 Marshal.Copy(loc, v, 0, 1);
696 public class CharElementTraits : Primitive32ElementTraits<char>, IBaseElementTraits<char>
698 override public void ManagedToNativeCopyTo(char man, IntPtr mem)
700 var arr = new char[1];
702 Marshal.Copy(arr, 0, mem, 1);
705 override public char NativeToManagedInlistNode(IntPtr nat)
707 if (nat == IntPtr.Zero)
709 Eina.Log.Error("Null pointer for Inlist node.");
710 return default(char);
713 IntPtr loc = nat + Marshal.SizeOf<InlistMem>();
715 Marshal.Copy(loc, v, 0, 1);
720 public class LongElementTraits : Primitive64ElementTraits<long>, IBaseElementTraits<long>
722 override public void ManagedToNativeCopyTo(long man, IntPtr mem)
724 var arr = new long[1];
726 Marshal.Copy(arr, 0, mem, 1);
729 override public long NativeToManagedInlistNode(IntPtr nat)
731 if (nat == IntPtr.Zero)
733 Eina.Log.Error("Null pointer for Inlist node.");
734 return default(long);
737 IntPtr loc = nat + Marshal.SizeOf<InlistMem>();
739 Marshal.Copy(loc, v, 0, 1);
744 public class ShortElementTraits : Primitive32ElementTraits<short>, IBaseElementTraits<short>
746 override public void ManagedToNativeCopyTo(short man, IntPtr mem)
748 var arr = new short[1];
750 Marshal.Copy(arr, 0, mem, 1);
753 override public short NativeToManagedInlistNode(IntPtr nat)
755 if (nat == IntPtr.Zero)
757 Eina.Log.Error("Null pointer for Inlist node.");
758 return default(short);
761 IntPtr loc = nat + Marshal.SizeOf<InlistMem>();
762 var v = new short[1];
763 Marshal.Copy(loc, v, 0, 1);
768 public class FloatElementTraits : Primitive32ElementTraits<float>, IBaseElementTraits<float>
770 override public void ManagedToNativeCopyTo(float man, IntPtr mem)
772 var arr = new float[1];
774 Marshal.Copy(arr, 0, mem, 1);
777 override public float NativeToManagedInlistNode(IntPtr nat)
779 if (nat == IntPtr.Zero)
781 Eina.Log.Error("Null pointer for Inlist node.");
782 return default(float);
785 IntPtr loc = nat + Marshal.SizeOf<InlistMem>();
786 var v = new float[1];
787 Marshal.Copy(loc, v, 0, 1);
792 public class DoubleElementTraits : Primitive64ElementTraits<double>, IBaseElementTraits<double>
794 override public void ManagedToNativeCopyTo(double man, IntPtr mem)
796 var arr = new double[1];
798 Marshal.Copy(arr, 0, mem, 1);
801 override public double NativeToManagedInlistNode(IntPtr nat)
803 if (nat == IntPtr.Zero)
805 Eina.Log.Error("Null pointer for Inlist node.");
806 return default(double);
809 IntPtr loc = nat + Marshal.SizeOf<InlistMem>();
810 var v = new double[1];
811 Marshal.Copy(loc, v, 0, 1);
816 public class ByteElementTraits : Primitive32ElementTraits<byte>, IBaseElementTraits<byte>
818 override public void ManagedToNativeCopyTo(byte man, IntPtr mem)
820 var arr = new byte[1];
822 Marshal.Copy(arr, 0, mem, 1);
825 override public byte NativeToManagedInlistNode(IntPtr nat)
827 if (nat == IntPtr.Zero)
829 Eina.Log.Error("Null pointer for Inlist node.");
830 return default(byte);
833 IntPtr loc = nat + Marshal.SizeOf<InlistMem>();
835 Marshal.Copy(loc, v, 0, 1);
840 public static class TraitFunctions
842 public static bool IsEflObject(System.Type type)
844 return typeof(Efl.Eo.IWrapper).IsAssignableFrom(type);
847 public static bool IsString(System.Type type)
849 return type == typeof(string);
852 public static bool IsStringshare(System.Type type)
854 return type == typeof(Eina.Stringshare);
857 public static Eina.ElementType GetElementTypeCode(System.Type type)
859 if (IsEflObject(type))
861 return ElementType.ObjectType;
863 else if (IsString(type))
865 return ElementType.StringType;
867 else if (IsStringshare(type))
869 return ElementType.StringshareType;
873 return ElementType.NumericType;
877 private static IDictionary<System.Type, object> register = new Dictionary<System.Type, object>();
879 private static System.Type AsEflInstantiableType(System.Type type)
881 if (!IsEflObject(type))
886 if (type.IsInterface)
888 string fullName = type.FullName + "Concrete";
889 return type.Assembly.GetType(fullName); // That was our best guess...
892 return type; // Not interface, so it should be a concrete.
895 public static object RegisterTypeTraits<T>()
897 Eina.Log.Debug($"Finding TypeTraits for {typeof(T).Name}");
899 var type = typeof(T);
900 if (IsEflObject(type))
902 System.Type concrete = AsEflInstantiableType(type);
903 if (concrete == null || !type.IsAssignableFrom(concrete))
905 throw new Exception("Failed to get a suitable concrete class for this type.");
908 // No need to pass concrete as the traits class will use reflection to get the actually most
909 // derived type returned.
910 traits = new EflObjectElementTraits<T>();
912 else if (IsString(type))
914 traits = new StringElementTraits();
916 else if (IsStringshare(type))
918 traits = new StringshareElementTraits();
920 else if (type.IsValueType)
922 if (type == typeof(int))
924 traits = new IntElementTraits();
926 else if (type == typeof(char))
928 traits = new CharElementTraits();
930 else if (type == typeof(long))
932 traits = new LongElementTraits();
934 else if (type == typeof(short))
936 traits = new ShortElementTraits();
938 else if (type == typeof(float))
940 traits = new FloatElementTraits();
942 else if (type == typeof(double))
944 traits = new DoubleElementTraits();
946 else if (type == typeof(byte))
948 traits = new ByteElementTraits();
952 throw new Exception("No traits registered for this type");
957 throw new Exception("No traits registered for this type");
960 register[type] = traits;
964 public static object RegisterTypeTraits<T>(IBaseElementTraits<T> traits)
966 register[typeof(T)] = traits;
970 public static IBaseElementTraits<T> GetTypeTraits<T>()
973 if (!register.TryGetValue(typeof(T), out traits))
975 traits = RegisterTypeTraits<T>();
978 return (IBaseElementTraits<T>)traits;
982 // Traits functions //
985 // Convertion functions //
987 public static IntPtr ManagedToNativeAlloc<T>(T man)
989 return GetTypeTraits<T>().ManagedToNativeAlloc(man);
992 public static void ManagedToNativeCopyTo<T>(T man, IntPtr mem)
994 GetTypeTraits<T>().ManagedToNativeCopyTo(man, mem);
997 public static IntPtr ManagedToNativeAllocInlistNode<T>(T man)
999 return GetTypeTraits<T>().ManagedToNativeAllocInlistNode(man);
1002 public static void NativeFree<T>(IntPtr nat)
1004 GetTypeTraits<T>().NativeFree(nat);
1007 public static void NativeFreeInlistNodeElement<T>(IntPtr nat)
1009 GetTypeTraits<T>().NativeFreeInlistNodeElement(nat);
1012 public static void NativeFreeInlistNode<T>(IntPtr nat, bool freeElement = true)
1014 GetTypeTraits<T>().NativeFreeInlistNode(nat, freeElement);
1017 public static void NativeFreeInplace<T>(IntPtr nat)
1019 GetTypeTraits<T>().NativeFreeInplace(nat);
1022 public static void ResidueFreeInplace<T>(IntPtr nat)
1024 GetTypeTraits<T>().ResidueFreeInplace(nat);
1027 public static T NativeToManaged<T>(IntPtr nat)
1029 return GetTypeTraits<T>().NativeToManaged(nat);
1032 public static T NativeToManagedInlistNode<T>(IntPtr nat)
1034 return GetTypeTraits<T>().NativeToManagedInlistNode(nat);
1037 public static T NativeToManagedInplace<T>(IntPtr nat)
1039 return GetTypeTraits<T>().NativeToManagedInplace(nat);
1044 public static IntPtr EinaCompareCb<T>()
1046 return GetTypeTraits<T>().EinaCompareCb();
1049 public static IntPtr EinaFreeCb<T>()
1051 return GetTypeTraits<T>().EinaFreeCb();
1054 public static IntPtr EinaHashNew<TKey>()
1056 return GetTypeTraits<TKey>().EinaHashNew();
1059 public static IntPtr EinaInarrayNew<T>(uint step)
1061 return GetTypeTraits<T>().EinaInarrayNew(step);
1064 public static IntPtr EinaHashIteratorKeyNew<T>(IntPtr hash)
1066 return GetTypeTraits<T>().EinaHashIteratorKeyNew(hash);