summaryrefslogtreecommitdiff
path: root/src/bindings
diff options
context:
space:
mode:
Diffstat (limited to 'src/bindings')
-rw-r--r--src/bindings/cxx/eina_cxx/eina_variant.hh16
-rw-r--r--src/bindings/luajit/eolian.lua20
-rw-r--r--src/bindings/mono/ecore_evas_mono/ecore_evas.cs38
-rw-r--r--src/bindings/mono/ecore_evas_mono/meson.build1
-rw-r--r--src/bindings/mono/efl_mono/efl_all.cs18
-rw-r--r--src/bindings/mono/efl_mono/efl_libs.cs.in17
-rw-r--r--src/bindings/mono/eina_mono/eina_common.cs10
-rw-r--r--src/bindings/mono/eina_mono/eina_container_common.cs353
-rw-r--r--src/bindings/mono/eina_mono/eina_hash.cs151
-rw-r--r--src/bindings/mono/eina_mono/eina_inarray.cs28
-rw-r--r--src/bindings/mono/eina_mono/eina_value.cs425
-rw-r--r--src/bindings/mono/eldbus_mono/eldbus_connection.cs2
-rw-r--r--src/bindings/mono/eldbus_mono/eldbus_message.cs34
-rw-r--r--src/bindings/mono/eldbus_mono/eldbus_object.cs4
-rw-r--r--src/bindings/mono/eldbus_mono/eldbus_pending.cs8
-rw-r--r--src/bindings/mono/eldbus_mono/eldbus_proxy.cs2
-rw-r--r--src/bindings/mono/eo_mono/FunctionWrapper.cs97
-rw-r--r--src/bindings/mono/eo_mono/FunctionWrapper_Unix.cs21
-rw-r--r--src/bindings/mono/eo_mono/FunctionWrapper_Windows.cs15
-rw-r--r--src/bindings/mono/eo_mono/NativeModule.cs33
-rw-r--r--src/bindings/mono/eo_mono/NativeModule_Unix.cs46
-rw-r--r--src/bindings/mono/eo_mono/NativeModule_Windows.cs15
-rw-r--r--src/bindings/mono/eo_mono/iwrapper.cs254
-rw-r--r--src/bindings/mono/eo_mono/meson.build10
-rw-r--r--src/bindings/mono/eo_mono/workaround.cs8
-rw-r--r--src/bindings/mono/meson.build59
26 files changed, 1273 insertions, 412 deletions
diff --git a/src/bindings/cxx/eina_cxx/eina_variant.hh b/src/bindings/cxx/eina_cxx/eina_variant.hh
index 358688a..4885c80 100644
--- a/src/bindings/cxx/eina_cxx/eina_variant.hh
+++ b/src/bindings/cxx/eina_cxx/eina_variant.hh
@@ -6,6 +6,7 @@
6#include <utility> 6#include <utility>
7#include <type_traits> 7#include <type_traits>
8#include <tuple> 8#include <tuple>
9#include <iosfwd>
9 10
10#include <eina_aligned_union.hh> 11#include <eina_aligned_union.hh>
11 12
@@ -149,6 +150,17 @@ struct destroy_visitor
149 } 150 }
150}; 151};
151 152
153struct ostream_visitor
154{
155 std::ostream* s;
156 typedef std::ostream& result_type;
157 template <typename T>
158 std::ostream& operator()(T const& other) const
159 {
160 return *s << other;
161 }
162};
163
152template <typename T> 164template <typename T>
153struct get_visitor 165struct get_visitor
154{ 166{
@@ -295,6 +307,10 @@ private:
295 && (rhs.type == -1 307 && (rhs.type == -1
296 || rhs.visit(compare_equal_visitor{&lhs.buffer})); 308 || rhs.visit(compare_equal_visitor{&lhs.buffer}));
297 } 309 }
310 friend std::ostream& operator<<(std::ostream& s, variant<Args...> const& rhs)
311 {
312 return rhs.visit(ostream_visitor{&s});
313 }
298 314
299 int type; 315 int type;
300 /** 316 /**
diff --git a/src/bindings/luajit/eolian.lua b/src/bindings/luajit/eolian.lua
index 098e8a5..0e72db3 100644
--- a/src/bindings/luajit/eolian.lua
+++ b/src/bindings/luajit/eolian.lua
@@ -153,8 +153,6 @@ ffi.cdef [[
153 EOLIAN_TYPE_BUILTIN_ITERATOR, 153 EOLIAN_TYPE_BUILTIN_ITERATOR,
154 EOLIAN_TYPE_BUILTIN_HASH, 154 EOLIAN_TYPE_BUILTIN_HASH,
155 EOLIAN_TYPE_BUILTIN_LIST, 155 EOLIAN_TYPE_BUILTIN_LIST,
156 EOLIAN_TYPE_BUILTIN_INARRAY,
157 EOLIAN_TYPE_BUILTIN_INLIST,
158 156
159 EOLIAN_TYPE_BUILTIN_ANY_VALUE, 157 EOLIAN_TYPE_BUILTIN_ANY_VALUE,
160 EOLIAN_TYPE_BUILTIN_ANY_VALUE_PTR, 158 EOLIAN_TYPE_BUILTIN_ANY_VALUE_PTR,
@@ -838,19 +836,17 @@ M.type_builtin_type = {
838 ITERATOR = 37, 836 ITERATOR = 37,
839 HASH = 38, 837 HASH = 38,
840 LIST = 39, 838 LIST = 39,
841 INARRAY = 40,
842 INLIST = 41,
843 839
844 ANY_VALUE = 42, 840 ANY_VALUE = 40,
845 ANY_VALUE_PTR = 43, 841 ANY_VALUE_PTR = 41,
846 842
847 MSTRING = 44, 843 MSTRING = 42,
848 STRING = 45, 844 STRING = 43,
849 STRINGSHARE = 46, 845 STRINGSHARE = 44,
850 STRBUF = 47. 846 STRBUF = 45,
851 847
852 VOID_PTR = 48, 848 VOID_PTR = 46,
853 FREE_CB = 49 849 FREE_CB = 47
854} 850}
855 851
856M.typedecl_type = { 852M.typedecl_type = {
diff --git a/src/bindings/mono/ecore_evas_mono/ecore_evas.cs b/src/bindings/mono/ecore_evas_mono/ecore_evas.cs
deleted file mode 100644
index 68993fb..0000000
--- a/src/bindings/mono/ecore_evas_mono/ecore_evas.cs
+++ /dev/null
@@ -1,38 +0,0 @@
1#pragma warning disable 1591
2
3using System;
4using System.Runtime.InteropServices;
5using System.Threading;
6
7public class EcoreEvas
8{
9 [DllImport(efl.Libs.EcoreEvas)] static extern void ecore_evas_init();
10 // [DllImport(efl.Libs.EcoreEvas)] static extern IntPtr ecore_evas_new([MarshalAs(UnmanagedType.LPStr)] String engine_name, int x, int y, int w, int h
11 // , [MarshalAs(UnmanagedType.LPStr)] String extra_options);
12 [DllImport(efl.Libs.EcoreEvas)] static extern IntPtr ecore_evas_new(IntPtr engine_name, int x, int y, int w, int h
13 , IntPtr extra_options);
14 [DllImport(efl.Libs.EcoreEvas)] static extern IntPtr ecore_evas_get(IntPtr ecore_evas);
15 [DllImport(efl.Libs.EcoreEvas)] static extern IntPtr ecore_evas_show(IntPtr ecore_evas);
16
17 IntPtr handle;
18 public EcoreEvas()
19 {
20#if WIN32 // Not a native define, we define it in our build system
21 // Ecore_Win32 uses OleInitialize, which requires single thread apartments
22 if (Thread.CurrentThread.GetApartmentState() != ApartmentState.STA)
23 throw new InvalidOperationException("UI Applications require STAThreadAttribute in Main()");
24#endif
25 ecore_evas_init();
26 handle = ecore_evas_new(IntPtr.Zero, 0, 0, 640, 480, IntPtr.Zero);
27 if(handle == IntPtr.Zero)
28 Eina.Log.Error("Couldn't create a ecore evas");
29 ecore_evas_show(handle);
30 }
31
32 public Efl.Canvas.Object canvas
33 {
34 get { return new Efl.Canvas.Object(ecore_evas_get(handle)); }
35 }
36
37}
38
diff --git a/src/bindings/mono/ecore_evas_mono/meson.build b/src/bindings/mono/ecore_evas_mono/meson.build
deleted file mode 100644
index 6020a63..0000000
--- a/src/bindings/mono/ecore_evas_mono/meson.build
+++ /dev/null
@@ -1 +0,0 @@
1mono_files += files('ecore_evas.cs')
diff --git a/src/bindings/mono/efl_mono/efl_all.cs b/src/bindings/mono/efl_mono/efl_all.cs
index a8436bd..d8c08d3 100644
--- a/src/bindings/mono/efl_mono/efl_all.cs
+++ b/src/bindings/mono/efl_mono/efl_all.cs
@@ -9,15 +9,31 @@ using static Efl.UnsafeNativeMethods;
9namespace Efl { 9namespace Efl {
10 10
11static class UnsafeNativeMethods { 11static class UnsafeNativeMethods {
12
13 private delegate void init_func_delegate();
12 [DllImport(efl.Libs.Ecore)] public static extern void ecore_init(); 14 [DllImport(efl.Libs.Ecore)] public static extern void ecore_init();
13 [DllImport(efl.Libs.Ecore)] public static extern void ecore_shutdown(); 15 [DllImport(efl.Libs.Ecore)] public static extern void ecore_shutdown();
14 [DllImport(efl.Libs.Evas)] public static extern void evas_init(); 16 // dotnet loads libraries from DllImport with RTLD_LOCAL. Due to the
17 // way evas modules are built with meson, currently they do not link directly
18 // with libevas, leading to symbol not found errors when trying to open them.
19 // The call to FunctionWrapper makes sure evas is loaded with RTLD_GLOBAL,
20 // allowing the symbols to remain visible for the modules until the build
21 // is sorted out.
22 private static Efl.Eo.FunctionWrapper<init_func_delegate> _evas_init;
15 [DllImport(efl.Libs.Evas)] public static extern void evas_shutdown(); 23 [DllImport(efl.Libs.Evas)] public static extern void evas_shutdown();
16 [DllImport(efl.Libs.Elementary)] public static extern int elm_init(int argc, IntPtr argv); 24 [DllImport(efl.Libs.Elementary)] public static extern int elm_init(int argc, IntPtr argv);
17 [DllImport(efl.Libs.Elementary)] public static extern void elm_policy_set(int policy, int policy_detail); 25 [DllImport(efl.Libs.Elementary)] public static extern void elm_policy_set(int policy, int policy_detail);
18 [DllImport(efl.Libs.Elementary)] public static extern void elm_shutdown(); 26 [DllImport(efl.Libs.Elementary)] public static extern void elm_shutdown();
19 [DllImport(efl.Libs.Elementary)] public static extern void elm_run(); 27 [DllImport(efl.Libs.Elementary)] public static extern void elm_run();
20 [DllImport(efl.Libs.Elementary)] public static extern void elm_exit(); 28 [DllImport(efl.Libs.Elementary)] public static extern void elm_exit();
29
30 static UnsafeNativeMethods() {
31 _evas_init = new Efl.Eo.FunctionWrapper<init_func_delegate>("evas", "evas_init");
32 }
33 public static void evas_init()
34 {
35 _evas_init.Value.Delegate();
36 }
21} 37}
22 38
23public enum Components { 39public enum Components {
diff --git a/src/bindings/mono/efl_mono/efl_libs.cs.in b/src/bindings/mono/efl_mono/efl_libs.cs.in
index 8674264..0aa5690 100644
--- a/src/bindings/mono/efl_mono/efl_libs.cs.in
+++ b/src/bindings/mono/efl_mono/efl_libs.cs.in
@@ -12,12 +12,27 @@ public class Libs {
12 public const string Eo = "@EO_DL_MONO@"; 12 public const string Eo = "@EO_DL_MONO@";
13 public const string Evas = "@EVAS_DL_MONO@"; 13 public const string Evas = "@EVAS_DL_MONO@";
14 public const string Evil = "@EVIL_DL_MONO@"; 14 public const string Evil = "@EVIL_DL_MONO@";
15 public const string EcoreEvas = "@ECORE_EVAS_DL_MONO@";
16 public const string Edje = "@EDJE_DL_MONO@"; 15 public const string Edje = "@EDJE_DL_MONO@";
17 public const string Elementary = "@ELEMENTARY_DL_MONO@"; 16 public const string Elementary = "@ELEMENTARY_DL_MONO@";
18 public const string Eldbus = "@ELDBUS_DL_MONO@"; 17 public const string Eldbus = "@ELDBUS_DL_MONO@";
19 18
20 public const string CustomExports = "@CUSTOM_EXPORTS_MONO_DL_MONO@"; 19 public const string CustomExports = "@CUSTOM_EXPORTS_MONO_DL_MONO@";
20
21 public const string Libdl = "libdl.so";
22 public const string Kernel32 = "kernel32.dll";
23
24 public static Efl.Eo.NativeModule EflModule = new Efl.Eo.NativeModule(Efl);
25 public static Efl.Eo.NativeModule CoreModule = new Efl.Eo.NativeModule(Ecore);
26 public static Efl.Eo.NativeModule EinaModule = new Efl.Eo.NativeModule(Eina);
27 public static Efl.Eo.NativeModule EoModule = new Efl.Eo.NativeModule(Eo);
28 public static Efl.Eo.NativeModule EvasModule = new Efl.Eo.NativeModule(Evas);
29 public static Efl.Eo.NativeModule EvilModule = new Efl.Eo.NativeModule(Evil);
30 public static Efl.Eo.NativeModule EdjeModule = new Efl.Eo.NativeModule(Edje);
31 public static Efl.Eo.NativeModule ElementaryModule = new Efl.Eo.NativeModule(Elementary);
32 public static Efl.Eo.NativeModule EldbusModule = new Efl.Eo.NativeModule(Eldbus);
33 public static Efl.Eo.NativeModule CustomExportsModule = new Efl.Eo.NativeModule(CustomExports);
34 public static Efl.Eo.NativeModule LibdlModule = new Efl.Eo.NativeModule(Libdl);
35 public static Efl.Eo.NativeModule Kernel32Module = new Efl.Eo.NativeModule(Kernel32);
21} 36}
22 37
23} 38}
diff --git a/src/bindings/mono/eina_mono/eina_common.cs b/src/bindings/mono/eina_mono/eina_common.cs
index e2ddc70..c9c10de 100644
--- a/src/bindings/mono/eina_mono/eina_common.cs
+++ b/src/bindings/mono/eina_mono/eina_common.cs
@@ -95,12 +95,6 @@ public static class MemoryNative {
95 } 95 }
96} 96}
97 97
98[StructLayout(LayoutKind.Sequential)]
99public struct ConvertWrapper<T>
100{
101 public T val;
102}
103
104public static class PrimitiveConversion 98public static class PrimitiveConversion
105{ 99{
106 public static T PointerToManaged<T>(IntPtr nat) 100 public static T PointerToManaged<T>(IntPtr nat)
@@ -111,8 +105,8 @@ public static class PrimitiveConversion
111 return default(T); 105 return default(T);
112 } 106 }
113 107
114 var w = Marshal.PtrToStructure<Eina.ConvertWrapper<T> >(nat); 108 var w = Marshal.PtrToStructure<T>(nat);
115 return w.val; 109 return w;
116 } 110 }
117 111
118 public static IntPtr ManagedToPointerAlloc<T>(T man) 112 public static IntPtr ManagedToPointerAlloc<T>(T man)
diff --git a/src/bindings/mono/eina_mono/eina_container_common.cs b/src/bindings/mono/eina_mono/eina_container_common.cs
index 838a7ed..3eddb2a 100644
--- a/src/bindings/mono/eina_mono/eina_container_common.cs
+++ b/src/bindings/mono/eina_mono/eina_container_common.cs
@@ -10,17 +10,11 @@ using static Eina.HashNativeFunctions;
10using static Eina.InarrayNativeFunctions; 10using static Eina.InarrayNativeFunctions;
11using static Eina.InlistNativeFunctions; 11using static Eina.InlistNativeFunctions;
12using static Eina.NativeCustomExportFunctions; 12using static Eina.NativeCustomExportFunctions;
13using static Eina.ContainerCommonData;
14 13
15namespace Eina { 14namespace Eina {
16 15
17public enum ElementType { NumericType, StringType, ObjectType }; 16public enum ElementType { NumericType, StringType, ObjectType };
18 17
19public static class ContainerCommonData
20{
21 public static IBaseElementTraits<IntPtr> intPtrTraits = null;
22}
23
24[StructLayout(LayoutKind.Sequential)] 18[StructLayout(LayoutKind.Sequential)]
25public struct InlistMem 19public struct InlistMem
26{ 20{
@@ -36,21 +30,17 @@ public struct InlistNode<T>
36 public T Val {get;set;} 30 public T Val {get;set;}
37} 31}
38 32
39
40public interface IBaseElementTraits<T> 33public interface IBaseElementTraits<T>
41{ 34{
42 IntPtr ManagedToNativeAlloc(T man); 35 IntPtr ManagedToNativeAlloc(T man);
43 IntPtr ManagedToNativeAllocRef(T man, bool refs);
44 IntPtr ManagedToNativeAllocInlistNode(T man); 36 IntPtr ManagedToNativeAllocInlistNode(T man);
45 IntPtr ManagedToNativeAllocInplace(T man); 37 void ManagedToNativeCopyTo(T man, IntPtr mem);
46 void NativeFree(IntPtr nat); 38 void NativeFree(IntPtr nat);
47 void NativeFreeRef(IntPtr nat, bool unrefs);
48 void NativeFreeInlistNodeElement(IntPtr nat); 39 void NativeFreeInlistNodeElement(IntPtr nat);
49 void NativeFreeInlistNode(IntPtr nat, bool freeElement); 40 void NativeFreeInlistNode(IntPtr nat, bool freeElement);
50 void NativeFreeInplace(IntPtr nat); 41 void NativeFreeInplace(IntPtr nat);
51 void ResidueFreeInplace(IntPtr nat); 42 void ResidueFreeInplace(IntPtr nat);
52 T NativeToManaged(IntPtr nat); 43 T NativeToManaged(IntPtr nat);
53 T NativeToManagedRef(IntPtr nat);
54 T NativeToManagedInlistNode(IntPtr nat); 44 T NativeToManagedInlistNode(IntPtr nat);
55 T NativeToManagedInplace(IntPtr nat); 45 T NativeToManagedInplace(IntPtr nat);
56 IntPtr EinaCompareCb(); 46 IntPtr EinaCompareCb();
@@ -60,40 +50,33 @@ public interface IBaseElementTraits<T>
60 IntPtr EinaHashIteratorKeyNew(IntPtr hash); 50 IntPtr EinaHashIteratorKeyNew(IntPtr hash);
61} 51}
62 52
63public class StringElementTraits<T> : IBaseElementTraits<T> 53public class StringElementTraits : IBaseElementTraits<string>
64{ 54{
65
66 public StringElementTraits() 55 public StringElementTraits()
67 { 56 {
68 if (intPtrTraits == null)
69 intPtrTraits = TraitFunctions.GetTypeTraits<IntPtr>();
70 }
71
72 public IntPtr ManagedToNativeAlloc(T man)
73 {
74 return MemoryNative.StrDup((string)(object)man);
75 } 57 }
76 58
77 public IntPtr ManagedToNativeAllocRef(T man, bool refs) 59 public IntPtr ManagedToNativeAlloc(string man)
78 { 60 {
79 // Keep alloc on C# ? 61 IntPtr newstring = MemoryNative.StrDup(man);
80 return ManagedToNativeAlloc(man); 62 return newstring;
81 } 63 }
82 64
83 public IntPtr ManagedToNativeAllocInlistNode(T man) 65 public IntPtr ManagedToNativeAllocInlistNode(string man)
84 { 66 {
85 var node = new InlistNode<IntPtr>(); 67 var node = new InlistNode<IntPtr>();
86 node.Val = ManagedToNativeAlloc(man); 68 node.Val = ManagedToNativeAlloc(man);
87 GCHandle pinnedData = GCHandle.Alloc(node, GCHandleType.Pinned); 69 GCHandle pinnedData = GCHandle.Alloc(node, GCHandleType.Pinned);
88 IntPtr ptr = pinnedData.AddrOfPinnedObject(); 70 IntPtr ptr = pinnedData.AddrOfPinnedObject();
89 IntPtr nat = MemoryNative.AllocCopy(ptr, Marshal.SizeOf<InlistNode<IntPtr> >()); 71 IntPtr nat = MemoryNative.AllocCopy(ptr, Marshal.SizeOf<InlistMem>() + Marshal.SizeOf<IntPtr>());
90 pinnedData.Free(); 72 pinnedData.Free();
91 return nat; 73 return nat;
92 } 74 }
93 75
94 public IntPtr ManagedToNativeAllocInplace(T man) 76 public void ManagedToNativeCopyTo(string man, IntPtr mem)
95 { 77 {
96 return intPtrTraits.ManagedToNativeAlloc(ManagedToNativeAlloc(man)); 78 IntPtr stringptr = ManagedToNativeAlloc(man);
79 Marshal.WriteIntPtr(mem, stringptr);
97 } 80 }
98 81
99 public void NativeFree(IntPtr nat) 82 public void NativeFree(IntPtr nat)
@@ -102,17 +85,13 @@ public class StringElementTraits<T> : IBaseElementTraits<T>
102 MemoryNative.Free(nat); 85 MemoryNative.Free(nat);
103 } 86 }
104 87
105 public void NativeFreeRef(IntPtr nat, bool unrefs)
106 {
107 NativeFree(nat);
108 }
109
110 public void NativeFreeInlistNodeElement(IntPtr nat) 88 public void NativeFreeInlistNodeElement(IntPtr nat)
111 { 89 {
112 if (nat == IntPtr.Zero) 90 if (nat == IntPtr.Zero)
113 return; 91 return;
114 var node = Marshal.PtrToStructure< InlistNode<IntPtr> >(nat); 92 var val = Marshal.PtrToStructure<IntPtr>
115 NativeFree(node.Val); 93 (nat + Marshal.SizeOf<InlistMem>());
94 NativeFree(val);
116 } 95 }
117 96
118 public void NativeFreeInlistNode(IntPtr nat, bool freeElement) 97 public void NativeFreeInlistNode(IntPtr nat, bool freeElement)
@@ -131,37 +110,35 @@ public class StringElementTraits<T> : IBaseElementTraits<T>
131 110
132 public void ResidueFreeInplace(IntPtr nat) 111 public void ResidueFreeInplace(IntPtr nat)
133 { 112 {
134 intPtrTraits.NativeFree(nat);
135 } 113 }
136 114
137 public T NativeToManaged(IntPtr nat) 115 public string NativeToManaged(IntPtr nat)
138 { 116 {
139 if (nat == IntPtr.Zero) 117 if (nat == IntPtr.Zero)
140 return default(T); 118 return default(string);
141 return (T)(object)StringConversion.NativeUtf8ToManagedString(nat); 119 return StringConversion.NativeUtf8ToManagedString(nat);
142 } 120 }
143 121
144 public T NativeToManagedRef(IntPtr nat) 122 public string NativeToManagedInlistNode(IntPtr nat)
145 {
146 return NativeToManaged(nat);
147 }
148
149 public T NativeToManagedInlistNode(IntPtr nat)
150 { 123 {
151 if (nat == IntPtr.Zero) 124 if (nat == IntPtr.Zero)
152 { 125 {
153 Eina.Log.Error("Null pointer for Inlist node."); 126 Eina.Log.Error("Null pointer for Inlist node.");
154 return default(T); 127 return default(string);
155 } 128 }
156 var w = Marshal.PtrToStructure< InlistNode<IntPtr> >(nat); 129 IntPtr ptr_location = nat + Marshal.SizeOf<InlistMem>();
157 return NativeToManaged(w.Val); 130 return NativeToManaged(Marshal.ReadIntPtr(ptr_location));
158 } 131 }
159 132
160 public T NativeToManagedInplace(IntPtr nat) 133 // Strings inplaced are always a pointer, because they are variable-sized
134 public string NativeToManagedInplace(IntPtr nat)
161 { 135 {
162 if (nat == IntPtr.Zero) 136 if (nat == IntPtr.Zero)
163 return default(T); 137 return default(string);
164 return NativeToManaged(intPtrTraits.NativeToManaged(nat)); 138 nat = Marshal.ReadIntPtr(nat);
139 if (nat == IntPtr.Zero)
140 return default(string);
141 return NativeToManaged(nat);
165 } 142 }
166 143
167 public IntPtr EinaCompareCb() 144 public IntPtr EinaCompareCb()
@@ -196,9 +173,6 @@ public class EflObjectElementTraits<T> : IBaseElementTraits<T>
196 173
197 public EflObjectElementTraits(System.Type concrete) 174 public EflObjectElementTraits(System.Type concrete)
198 { 175 {
199 if (intPtrTraits == null)
200 intPtrTraits = TraitFunctions.GetTypeTraits<IntPtr>();
201
202 concreteType = concrete; 176 concreteType = concrete;
203 } 177 }
204 178
@@ -210,26 +184,21 @@ public class EflObjectElementTraits<T> : IBaseElementTraits<T>
210 return Efl.Eo.Globals.efl_ref(h); 184 return Efl.Eo.Globals.efl_ref(h);
211 } 185 }
212 186
213 public IntPtr ManagedToNativeAllocRef(T man, bool refs)
214 {
215 IntPtr h = refs ? ManagedToNativeAlloc(man) : ((Efl.Eo.IWrapper)man).NativeHandle;
216 return intPtrTraits.ManagedToNativeAlloc(h);
217 }
218
219 public IntPtr ManagedToNativeAllocInlistNode(T man) 187 public IntPtr ManagedToNativeAllocInlistNode(T man)
220 { 188 {
221 var node = new InlistNode<IntPtr>(); 189 var node = new InlistNode<IntPtr>();
222 node.Val = ManagedToNativeAlloc(man); 190 node.Val = ManagedToNativeAlloc(man);
223 GCHandle pinnedData = GCHandle.Alloc(node, GCHandleType.Pinned); 191 GCHandle pinnedData = GCHandle.Alloc(node, GCHandleType.Pinned);
224 IntPtr ptr = pinnedData.AddrOfPinnedObject(); 192 IntPtr ptr = pinnedData.AddrOfPinnedObject();
225 IntPtr nat = MemoryNative.AllocCopy(ptr, Marshal.SizeOf<InlistNode<IntPtr> >()); 193 IntPtr nat = MemoryNative.AllocCopy(ptr, Marshal.SizeOf<InlistMem>() + Marshal.SizeOf<IntPtr>());
226 pinnedData.Free(); 194 pinnedData.Free();
227 return nat; 195 return nat;
228 } 196 }
229 197
230 public IntPtr ManagedToNativeAllocInplace(T man) 198 public void ManagedToNativeCopyTo(T man, IntPtr mem)
231 { 199 {
232 return intPtrTraits.ManagedToNativeAlloc(ManagedToNativeAlloc(man)); 200 IntPtr v = ManagedToNativeAlloc(man);
201 Marshal.WriteIntPtr(mem, v);
233 } 202 }
234 203
235 public void NativeFree(IntPtr nat) 204 public void NativeFree(IntPtr nat)
@@ -241,16 +210,16 @@ public class EflObjectElementTraits<T> : IBaseElementTraits<T>
241 public void NativeFreeRef(IntPtr nat, bool unrefs) 210 public void NativeFreeRef(IntPtr nat, bool unrefs)
242 { 211 {
243 if (unrefs) 212 if (unrefs)
244 NativeFree(intPtrTraits.NativeToManaged(nat)); 213 NativeFree(nat);
245 intPtrTraits.NativeFree(nat);
246 } 214 }
247 215
248 public void NativeFreeInlistNodeElement(IntPtr nat) 216 public void NativeFreeInlistNodeElement(IntPtr nat)
249 { 217 {
250 if (nat == IntPtr.Zero) 218 if (nat == IntPtr.Zero)
251 return; 219 return;
252 var node = Marshal.PtrToStructure< InlistNode<IntPtr> >(nat); 220 var val = Marshal.PtrToStructure<IntPtr>
253 NativeFree(node.Val); 221 (nat + Marshal.SizeOf<InlistMem>());
222 NativeFree(val);
254 } 223 }
255 224
256 public void NativeFreeInlistNode(IntPtr nat, bool freeElement) 225 public void NativeFreeInlistNode(IntPtr nat, bool freeElement)
@@ -264,12 +233,11 @@ public class EflObjectElementTraits<T> : IBaseElementTraits<T>
264 233
265 public void NativeFreeInplace(IntPtr nat) 234 public void NativeFreeInplace(IntPtr nat)
266 { 235 {
267 NativeFree(intPtrTraits.NativeToManaged(nat)); 236 NativeFree(nat);
268 } 237 }
269 238
270 public void ResidueFreeInplace(IntPtr nat) 239 public void ResidueFreeInplace(IntPtr nat)
271 { 240 {
272 intPtrTraits.NativeFree(nat);
273 } 241 }
274 242
275 public T NativeToManaged(IntPtr nat) 243 public T NativeToManaged(IntPtr nat)
@@ -283,7 +251,7 @@ public class EflObjectElementTraits<T> : IBaseElementTraits<T>
283 { 251 {
284 if (nat == IntPtr.Zero) 252 if (nat == IntPtr.Zero)
285 return default(T); 253 return default(T);
286 return NativeToManaged(intPtrTraits.NativeToManaged(nat)); 254 return NativeToManaged(nat);
287 } 255 }
288 256
289 public T NativeToManagedInlistNode(IntPtr nat) 257 public T NativeToManagedInlistNode(IntPtr nat)
@@ -293,15 +261,19 @@ public class EflObjectElementTraits<T> : IBaseElementTraits<T>
293 Eina.Log.Error("Null pointer for Inlist node."); 261 Eina.Log.Error("Null pointer for Inlist node.");
294 return default(T); 262 return default(T);
295 } 263 }
296 var w = Marshal.PtrToStructure< InlistNode<IntPtr> >(nat); 264 IntPtr ptr_location = nat + Marshal.SizeOf<InlistMem>();
297 return NativeToManaged(w.Val); 265 return NativeToManaged(Marshal.ReadIntPtr(ptr_location));
298 } 266 }
299 267
268 // EFL objects inplaced are always a pointer, because they are variable-sized
300 public T NativeToManagedInplace(IntPtr nat) 269 public T NativeToManagedInplace(IntPtr nat)
301 { 270 {
302 if (nat == IntPtr.Zero) 271 if (nat == IntPtr.Zero)
303 return default(T); 272 return default(T);
304 return NativeToManaged(intPtrTraits.NativeToManaged(nat)); 273 nat = Marshal.ReadIntPtr(nat);
274 if (nat == IntPtr.Zero)
275 return default(T);
276 return NativeToManaged(nat);
305 } 277 }
306 278
307 public IntPtr EinaCompareCb() 279 public IntPtr EinaCompareCb()
@@ -345,16 +317,12 @@ public abstract class PrimitiveElementTraits<T>
345 node.Val = man; 317 node.Val = man;
346 GCHandle pinnedData = GCHandle.Alloc(node, GCHandleType.Pinned); 318 GCHandle pinnedData = GCHandle.Alloc(node, GCHandleType.Pinned);
347 IntPtr ptr = pinnedData.AddrOfPinnedObject(); 319 IntPtr ptr = pinnedData.AddrOfPinnedObject();
348 IntPtr nat = MemoryNative.AllocCopy(ptr, Marshal.SizeOf< InlistNode<T> >()); 320 int Tsize = Marshal.SizeOf<T>() < Marshal.SizeOf<IntPtr>() ? Marshal.SizeOf<IntPtr>() : Marshal.SizeOf<T>();
321 IntPtr nat = MemoryNative.AllocCopy(ptr, Marshal.SizeOf<InlistMem>() + Tsize);
349 pinnedData.Free(); 322 pinnedData.Free();
350 return nat; 323 return nat;
351 } 324 }
352 325
353 public IntPtr ManagedToNativeAllocInplace(T man)
354 {
355 return ManagedToNativeAlloc(man);
356 }
357
358 public void NativeFree(IntPtr nat) 326 public void NativeFree(IntPtr nat)
359 { 327 {
360 MemoryNative.Free(nat); 328 MemoryNative.Free(nat);
@@ -395,16 +363,6 @@ public abstract class PrimitiveElementTraits<T>
395 return NativeToManaged(nat); 363 return NativeToManaged(nat);
396 } 364 }
397 365
398 public T NativeToManagedInlistNode(IntPtr nat)
399 {
400 if (nat == IntPtr.Zero)
401 {
402 Eina.Log.Error("Null pointer for Inlist node.");
403 return default(T);
404 }
405 var w = Marshal.PtrToStructure< InlistNode<T> >(nat);
406 return w.Val;
407 }
408 366
409 public T NativeToManagedInplace(IntPtr nat) 367 public T NativeToManagedInplace(IntPtr nat)
410 { 368 {
@@ -441,7 +399,7 @@ public abstract class PrimitiveElementTraits<T>
441 } 399 }
442} 400}
443 401
444public class Primitive32ElementTraits<T> : PrimitiveElementTraits<T>, IBaseElementTraits<T> 402abstract public class Primitive32ElementTraits<T> : PrimitiveElementTraits<T>, IBaseElementTraits<T>
445{ 403{
446 private static IBaseElementTraits<Int32> int32Traits = null; 404 private static IBaseElementTraits<Int32> int32Traits = null;
447 405
@@ -454,6 +412,9 @@ public class Primitive32ElementTraits<T> : PrimitiveElementTraits<T>, IBaseEleme
454 int32Traits = TraitFunctions.GetTypeTraits<Int32>(); 412 int32Traits = TraitFunctions.GetTypeTraits<Int32>();
455 } 413 }
456 414
415 public abstract void ManagedToNativeCopyTo(T man, IntPtr mem);
416 public abstract T NativeToManagedInlistNode(IntPtr nat);
417
457 public IntPtr ManagedToNativeAllocRef(T man, bool refs) 418 public IntPtr ManagedToNativeAllocRef(T man, bool refs)
458 { 419 {
459 return int32Traits.ManagedToNativeAlloc(Convert.ToInt32((object)man)); 420 return int32Traits.ManagedToNativeAlloc(Convert.ToInt32((object)man));
@@ -470,7 +431,7 @@ public class Primitive32ElementTraits<T> : PrimitiveElementTraits<T>, IBaseEleme
470 } 431 }
471} 432}
472 433
473public class Primitive64ElementTraits<T> : PrimitiveElementTraits<T>, IBaseElementTraits<T> 434abstract public class Primitive64ElementTraits<T> : PrimitiveElementTraits<T>, IBaseElementTraits<T>
474{ 435{
475 private static IBaseElementTraits<Int64> int64Traits = null; 436 private static IBaseElementTraits<Int64> int64Traits = null;
476 437
@@ -483,6 +444,9 @@ public class Primitive64ElementTraits<T> : PrimitiveElementTraits<T>, IBaseEleme
483 int64Traits = TraitFunctions.GetTypeTraits<Int64>(); 444 int64Traits = TraitFunctions.GetTypeTraits<Int64>();
484 } 445 }
485 446
447 public abstract void ManagedToNativeCopyTo(T man, IntPtr mem);
448 public abstract T NativeToManagedInlistNode(IntPtr nat);
449
486 public IntPtr ManagedToNativeAllocRef(T man, bool refs) 450 public IntPtr ManagedToNativeAllocRef(T man, bool refs)
487 { 451 {
488 return int64Traits.ManagedToNativeAlloc(Convert.ToInt64((object)man)); 452 return int64Traits.ManagedToNativeAlloc(Convert.ToInt64((object)man));
@@ -499,6 +463,159 @@ public class Primitive64ElementTraits<T> : PrimitiveElementTraits<T>, IBaseEleme
499 } 463 }
500} 464}
501 465
466public class IntElementTraits : Primitive32ElementTraits<int>, IBaseElementTraits<int>
467{
468 override public void ManagedToNativeCopyTo(int man, IntPtr mem)
469 {
470 var arr = new int[1];
471 arr[0] = man;
472 Marshal.Copy(arr, 0, mem, 1);
473 }
474 override public int NativeToManagedInlistNode(IntPtr nat)
475 {
476 if (nat == IntPtr.Zero)
477 {
478 Eina.Log.Error("Null pointer for Inlist node.");
479 return default(int);
480 }
481 IntPtr loc = nat + Marshal.SizeOf<InlistMem>();
482 var v = new int[1];
483 Marshal.Copy(loc, v, 0, 1);
484 return v[0];
485 }
486}
487
488public class CharElementTraits : Primitive32ElementTraits<char>, IBaseElementTraits<char>
489{
490 override public void ManagedToNativeCopyTo(char man, IntPtr mem)
491 {
492 var arr = new char[1];
493 arr[0] = man;
494 Marshal.Copy(arr, 0, mem, 1);
495 }
496 override public char NativeToManagedInlistNode(IntPtr nat)
497 {
498 if (nat == IntPtr.Zero)
499 {
500 Eina.Log.Error("Null pointer for Inlist node.");
501 return default(char);
502 }
503 IntPtr loc = nat + Marshal.SizeOf<InlistMem>();
504 var v = new char[1];
505 Marshal.Copy(loc, v, 0, 1);
506 return v[0];
507 }
508}
509public class LongElementTraits : Primitive64ElementTraits<long>, IBaseElementTraits<long>
510{
511 override public void ManagedToNativeCopyTo(long man, IntPtr mem)
512 {
513 var arr = new long[1];
514 arr[0] = man;
515 Marshal.Copy(arr, 0, mem, 1);
516 }
517 override public long NativeToManagedInlistNode(IntPtr nat)
518 {
519 if (nat == IntPtr.Zero)
520 {
521 Eina.Log.Error("Null pointer for Inlist node.");
522 return default(long);
523 }
524 IntPtr loc = nat + Marshal.SizeOf<InlistMem>();
525 var v = new long[1];
526 Marshal.Copy(loc, v, 0, 1);
527 return v[0];
528 }
529}
530
531public class ShortElementTraits : Primitive32ElementTraits<short>, IBaseElementTraits<short>
532{
533 override public void ManagedToNativeCopyTo(short man, IntPtr mem)
534 {
535 var arr = new short[1];
536 arr[0] = man;
537 Marshal.Copy(arr, 0, mem, 1);
538 }
539 override public short NativeToManagedInlistNode(IntPtr nat)
540 {
541 if (nat == IntPtr.Zero)
542 {
543 Eina.Log.Error("Null pointer for Inlist node.");
544 return default(short);
545 }
546 IntPtr loc = nat + Marshal.SizeOf<InlistMem>();
547 var v = new short[1];
548 Marshal.Copy(loc, v, 0, 1);
549 return v[0];
550 }
551}
552
553public class FloatElementTraits : Primitive32ElementTraits<float>, IBaseElementTraits<float>
554{
555 override public void ManagedToNativeCopyTo(float man, IntPtr mem)
556 {
557 var arr = new float[1];
558 arr[0] = man;
559 Marshal.Copy(arr, 0, mem, 1);
560 }
561 override public float NativeToManagedInlistNode(IntPtr nat)
562 {
563 if (nat == IntPtr.Zero)
564 {
565 Eina.Log.Error("Null pointer for Inlist node.");
566 return default(float);
567 }
568 IntPtr loc = nat + Marshal.SizeOf<InlistMem>();
569 var v = new float[1];
570 Marshal.Copy(loc, v, 0, 1);
571 return v[0];
572 }
573}
574
575public class DoubleElementTraits : Primitive64ElementTraits<double>, IBaseElementTraits<double>
576{
577 override public void ManagedToNativeCopyTo(double man, IntPtr mem)
578 {
579 var arr = new double[1];
580 arr[0] = man;
581 Marshal.Copy(arr, 0, mem, 1);
582 }
583 override public double NativeToManagedInlistNode(IntPtr nat)
584 {
585 if (nat == IntPtr.Zero)
586 {
587 Eina.Log.Error("Null pointer for Inlist node.");
588 return default(double);
589 }
590 IntPtr loc = nat + Marshal.SizeOf<InlistMem>();
591 var v = new double[1];
592 Marshal.Copy(loc, v, 0, 1);
593 return v[0];
594 }
595}
596
597public class ByteElementTraits : Primitive32ElementTraits<byte>, IBaseElementTraits<byte>
598{
599 override public void ManagedToNativeCopyTo(byte man, IntPtr mem)
600 {
601 var arr = new byte[1];
602 arr[0] = man;
603 Marshal.Copy(arr, 0, mem, 1);
604 }
605 override public byte NativeToManagedInlistNode(IntPtr nat)
606 {
607 if (nat == IntPtr.Zero)
608 {
609 Eina.Log.Error("Null pointer for Inlist node.");
610 return default(byte);
611 }
612 IntPtr loc = nat + Marshal.SizeOf<InlistMem>();
613 var v = new byte[1];
614 Marshal.Copy(loc, v, 0, 1);
615 return v[0];
616 }
617}
618
502public static class TraitFunctions 619public static class TraitFunctions
503{ 620{
504 public static bool IsEflObject(System.Type type) 621 public static bool IsEflObject(System.Type type)
@@ -530,27 +647,16 @@ public static class TraitFunctions
530 647
531 if (type.IsInterface) 648 if (type.IsInterface)
532 { 649 {
533 string[] names = type.FullName.Split('.'); 650 string fullName = type.FullName + "Concrete";
534 names[names.Count() - 1] = names.Last().Substring(1); // Remove the leading 'I' (What about user-defined interfaces?)
535
536 string fullName = string.Join(".", names);
537 return type.Assembly.GetType(fullName); // That was our best guess... 651 return type.Assembly.GetType(fullName); // That was our best guess...
538 } 652 }
539 653
540 654 return type; // Not interface, so it should be a concrete.
541 System.Type current = type;
542 while (current != null)
543 {
544 if (current.Name.EndsWith("Inherit"))
545 throw new Exception("Inherit-based classes are not currently supported.");
546 current = current.BaseType;
547 }
548
549 return type; // Not inherited neither interface, so it should be a concrete.
550 } 655 }
551 656
552 public static object RegisterTypeTraits<T>() 657 public static object RegisterTypeTraits<T>()
553 { 658 {
659 Eina.Log.Debug($"Finding TypeTraits for {typeof(T).Name}");
554 object traits; 660 object traits;
555 var type = typeof(T); 661 var type = typeof(T);
556 if (IsEflObject(type)) 662 if (IsEflObject(type))
@@ -561,13 +667,25 @@ public static class TraitFunctions
561 traits = new EflObjectElementTraits<T>(concrete); 667 traits = new EflObjectElementTraits<T>(concrete);
562 } 668 }
563 else if (IsString(type)) 669 else if (IsString(type))
564 traits = new StringElementTraits<T>(); 670 traits = new StringElementTraits();
565 else if (type.IsValueType) 671 else if (type.IsValueType)
566 { 672 {
567 if (Marshal.SizeOf<T>() <= 4) 673 if (type == typeof(int))
568 traits = new Primitive32ElementTraits<T>(); 674 traits = new IntElementTraits();
675 else if (type == typeof(char))
676 traits = new CharElementTraits();
677 else if (type == typeof(long))
678 traits = new LongElementTraits();
679 else if (type == typeof(short))
680 traits = new ShortElementTraits();
681 else if (type == typeof(float))
682 traits = new FloatElementTraits();
683 else if (type == typeof(double))
684 traits = new DoubleElementTraits();
685 else if (type == typeof(byte))
686 traits = new ByteElementTraits();
569 else 687 else
570 traits = new Primitive64ElementTraits<T>(); 688 throw new Exception("No traits registered for this type");
571 } 689 }
572 else 690 else
573 throw new Exception("No traits registered for this type"); 691 throw new Exception("No traits registered for this type");
@@ -601,14 +719,9 @@ public static class TraitFunctions
601 return GetTypeTraits<T>().ManagedToNativeAlloc(man); 719 return GetTypeTraits<T>().ManagedToNativeAlloc(man);
602 } 720 }
603 721
604 public static IntPtr ManagedToNativeAllocRef<T>(T man, bool refs = false) 722 public static void ManagedToNativeCopyTo<T>(T man, IntPtr mem)
605 { 723 {
606 return GetTypeTraits<T>().ManagedToNativeAllocRef(man, refs); 724 GetTypeTraits<T>().ManagedToNativeCopyTo(man, mem);
607 }
608
609 public static IntPtr ManagedToNativeAllocInplace<T>(T man)
610 {
611 return GetTypeTraits<T>().ManagedToNativeAllocInplace(man);
612 } 725 }
613 726
614 public static IntPtr ManagedToNativeAllocInlistNode<T>(T man) 727 public static IntPtr ManagedToNativeAllocInlistNode<T>(T man)
@@ -621,11 +734,6 @@ public static class TraitFunctions
621 GetTypeTraits<T>().NativeFree(nat); 734 GetTypeTraits<T>().NativeFree(nat);
622 } 735 }
623 736
624 public static void NativeFreeRef<T>(IntPtr nat, bool unrefs = false)
625 {
626 GetTypeTraits<T>().NativeFreeRef(nat, unrefs);
627 }
628
629 public static void NativeFreeInlistNodeElement<T>(IntPtr nat) 737 public static void NativeFreeInlistNodeElement<T>(IntPtr nat)
630 { 738 {
631 GetTypeTraits<T>().NativeFreeInlistNodeElement(nat); 739 GetTypeTraits<T>().NativeFreeInlistNodeElement(nat);
@@ -651,11 +759,6 @@ public static class TraitFunctions
651 return GetTypeTraits<T>().NativeToManaged(nat); 759 return GetTypeTraits<T>().NativeToManaged(nat);
652 } 760 }
653 761
654 public static T NativeToManagedRef<T>(IntPtr nat)
655 {
656 return GetTypeTraits<T>().NativeToManagedRef(nat);
657 }
658
659 public static T NativeToManagedInlistNode<T>(IntPtr nat) 762 public static T NativeToManagedInlistNode<T>(IntPtr nat)
660 { 763 {
661 return GetTypeTraits<T>().NativeToManagedInlistNode(nat); 764 return GetTypeTraits<T>().NativeToManagedInlistNode(nat);
diff --git a/src/bindings/mono/eina_mono/eina_hash.cs b/src/bindings/mono/eina_mono/eina_hash.cs
index 590033e..95de7c5 100644
--- a/src/bindings/mono/eina_mono/eina_hash.cs
+++ b/src/bindings/mono/eina_mono/eina_hash.cs
@@ -242,10 +242,13 @@ public class Hash<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>, IDi
242 242
243 public bool AddNew(TKey key, TValue val) 243 public bool AddNew(TKey key, TValue val)
244 { 244 {
245 var nk = ManagedToNativeAllocRef(key, true); 245 IntPtr gchnk = CopyNativeObject(key, ForceRefKey<TKey>());
246 var nv = ManagedToNativeAlloc(val); 246 IntPtr nk = GetNativePtr<TKey>(gchnk, ForceRefKey<TKey>());
247 IntPtr gchnv = CopyNativeObject(val, false);
248 IntPtr nv = GetNativePtr<TValue>(gchnv, false);
247 var r = eina_hash_add(Handle, nk, nv); 249 var r = eina_hash_add(Handle, nk, nv);
248 NativeFreeRef<TKey>(nk); 250 FreeNativeIndirection<TKey>(gchnk, ForceRefKey<TKey>());
251 FreeNativeIndirection<TValue>(gchnv, false);
249 return r; 252 return r;
250 } 253 }
251 254
@@ -256,17 +259,20 @@ public class Hash<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>, IDi
256 259
257 public bool DelByKey(TKey key) 260 public bool DelByKey(TKey key)
258 { 261 {
259 var nk = ManagedToNativeAllocRef(key); 262 IntPtr gchnk = CopyNativeObject(key, ForceRefKey<TKey>());
263 IntPtr nk = GetNativePtr<TKey>(gchnk, ForceRefKey<TKey>());
260 var r = eina_hash_del_by_key(Handle, nk); 264 var r = eina_hash_del_by_key(Handle, nk);
261 NativeFreeRef<TKey>(nk, OwnKey && r); 265 FreeNativeIndirection<TKey>(gchnk, ForceRefKey<TKey>());
266 // NativeFreeRef<TKey>(nk, OwnKey && r);
262 return r; 267 return r;
263 } 268 }
264 269
265 public bool DelByValue(TValue val) 270 public bool DelByValue(TValue val)
266 { 271 {
267 var nv = ManagedToNativeAlloc(val); 272 IntPtr gchnv = CopyNativeObject(val, false);
273 IntPtr nv = GetNativePtr<TValue>(gchnv, false);
268 var r = eina_hash_del_by_data(Handle, nv); 274 var r = eina_hash_del_by_data(Handle, nv);
269 NativeFree<TValue>(nv); 275 FreeNativeIndirection<TValue>(gchnv, false);
270 return r; 276 return r;
271 } 277 }
272 278
@@ -277,42 +283,52 @@ public class Hash<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>, IDi
277 283
278 public TValue Find(TKey key) 284 public TValue Find(TKey key)
279 { 285 {
280 var nk = ManagedToNativeAllocRef(key); 286 var gchnk = CopyNativeObject<TKey>(key, ForceRefKey<TKey>());
287 var nk = GetNativePtr<TKey>(gchnk, ForceRefKey<TKey>());
281 var found = eina_hash_find(Handle, nk); 288 var found = eina_hash_find(Handle, nk);
282 NativeFreeRef<TKey>(nk); 289 //NativeFreeRef<TKey>(nk);
290 FreeNativeIndirection<TKey>(gchnk, ForceRefKey<TKey>());
283 if (found == IntPtr.Zero) 291 if (found == IntPtr.Zero)
284 throw new KeyNotFoundException(); 292 throw new KeyNotFoundException();
285 return NativeToManaged<TValue>(found); 293
294 return NativeToManaged<TValue>(IndirectNative<TValue>(found, false));
286 } 295 }
287 296
288 public bool TryGetValue(TKey key, out TValue val) 297 public bool TryGetValue(TKey key, out TValue val)
289 { 298 {
290 var nk = ManagedToNativeAllocRef(key); 299 var gchnk = CopyNativeObject<TKey>(key, ForceRefKey<TKey>());
300 var nk = GetNativePtr<TKey>(gchnk, ForceRefKey<TKey>());
291 var found = eina_hash_find(Handle, nk); 301 var found = eina_hash_find(Handle, nk);
292 NativeFreeRef<TKey>(nk); 302 FreeNativeIndirection<TKey>(gchnk, ForceRefKey<TKey>());
293 if (found == IntPtr.Zero) 303 if (found == IntPtr.Zero)
294 { 304 {
295 val = default(TValue); 305 val = default(TValue);
296 return false; 306 return false;
297 } 307 }
298 val = NativeToManaged<TValue>(found); 308 val = NativeToManaged<TValue>(IndirectNative<TValue>(found, false));
299 return true; 309 return true;
300 } 310 }
301 311
302 public bool ContainsKey(TKey key) 312 public bool ContainsKey(TKey key)
303 { 313 {
304 var nk = ManagedToNativeAllocRef(key); 314 var gchnk = CopyNativeObject<TKey>(key, ForceRefKey<TKey>());
315 var nk = GetNativePtr<TKey>(gchnk, ForceRefKey<TKey>());
316 // var nk = ManagedToNativeAllocRef(key);
305 var found = eina_hash_find(Handle, nk); 317 var found = eina_hash_find(Handle, nk);
306 NativeFreeRef<TKey>(nk); 318 // NativeFreeRef<TKey>(nk);
319 FreeNativeIndirection<TKey>(gchnk, ForceRefKey<TKey>());
307 return found != IntPtr.Zero; 320 return found != IntPtr.Zero;
308 } 321 }
309 322
310 public bool Modify(TKey key, TValue val) 323 public bool Modify(TKey key, TValue val)
311 { 324 {
312 var nk = ManagedToNativeAllocRef(key); 325 var gchnk = CopyNativeObject<TKey>(key, ForceRefKey<TKey>());
313 var nv = ManagedToNativeAlloc(val); 326 var nk = GetNativePtr<TKey>(gchnk, ForceRefKey<TKey>());
327 var gchnv = CopyNativeObject<TValue>(val, false);
328 var nv = GetNativePtr<TValue>(gchnv, false);
314 var old = eina_hash_modify(Handle, nk, nv); 329 var old = eina_hash_modify(Handle, nk, nv);
315 NativeFreeRef<TKey>(nk); 330 FreeNativeIndirection<TKey>(gchnk, ForceRefKey<TKey>());
331 // NativeFreeRef<TKey>(nk);
316 if (old == IntPtr.Zero) 332 if (old == IntPtr.Zero)
317 { 333 {
318 NativeFree<TValue>(nv); 334 NativeFree<TValue>(nv);
@@ -323,13 +339,83 @@ public class Hash<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>, IDi
323 return true; 339 return true;
324 } 340 }
325 341
342 private static bool ForceRefKey<T>()
343 {
344 return (!typeof(T).IsValueType) && (typeof(T) != typeof(string));
345 }
346
347 private static IntPtr CopyNativeObject<T>(T value, bool forceRef)
348 {
349 if (!IsEflObject(typeof(T)) && forceRef)
350 {
351 GCHandle gch = GCHandle.Alloc(new byte[Marshal.SizeOf<T>()], GCHandleType.Pinned);
352 IntPtr pin = gch.AddrOfPinnedObject();
353
354 ManagedToNativeCopyTo(value, pin);
355
356 return GCHandle.ToIntPtr(gch);
357 }
358 else if(IsEflObject(typeof(T)) && forceRef)
359 {
360 GCHandle gch = GCHandle.Alloc(new byte[Marshal.SizeOf<IntPtr>()], GCHandleType.Pinned);
361 IntPtr pin = gch.AddrOfPinnedObject();
362
363 ManagedToNativeCopyTo(value, pin);
364
365 return GCHandle.ToIntPtr(gch);
366 }
367 else
368 {
369 return ManagedToNativeAlloc(value);
370 }
371 }
372 private static IntPtr GetNativePtr<T>(IntPtr gchptr, bool forceRef)
373 {
374 if (forceRef)
375 {
376 GCHandle gch = GCHandle.FromIntPtr(gchptr);
377 IntPtr pin = gch.AddrOfPinnedObject();
378
379 return pin;
380 }
381 else
382 {
383 return gchptr;
384 }
385 }
386 private static void FreeNativeIndirection<T>(IntPtr gchptr, bool forceRef)
387 {
388 if (forceRef)
389 {
390 GCHandle gch = GCHandle.FromIntPtr(gchptr);
391 gch.Free();
392 }
393 }
394
395 private static IntPtr IndirectNative<T>(IntPtr ptr, bool forceRef)
396 {
397 if (forceRef)
398 {
399 IntPtr val = Marshal.ReadIntPtr(ptr);
400 return val;
401 }
402 else
403 {
404 return ptr;
405 }
406 }
407
326 public void Set(TKey key, TValue val) 408 public void Set(TKey key, TValue val)
327 { 409 {
328 var nk = ManagedToNativeAllocRef(key, true); 410 IntPtr gchnk = CopyNativeObject(key, ForceRefKey<TKey>());
329 var nv = ManagedToNativeAlloc(val); 411 IntPtr nk = GetNativePtr<TKey>(gchnk, ForceRefKey<TKey>());
330 var old = eina_hash_set(Handle, nk, nv); 412
331 NativeFreeRef<TKey>(nk, old != IntPtr.Zero); 413 IntPtr gchnv = CopyNativeObject(val, false);
332 if (old != IntPtr.Zero && OwnValue) 414 IntPtr nv = GetNativePtr<TValue>(gchnv, false);
415 IntPtr old = eina_hash_set(Handle, nk, nv);
416 FreeNativeIndirection<TKey>(gchnk, ForceRefKey<TKey>());
417 FreeNativeIndirection<TValue>(gchnv, false);
418 if (OwnValue || old != IntPtr.Zero)
333 NativeFree<TValue>(old); 419 NativeFree<TValue>(old);
334 } 420 }
335 421
@@ -347,11 +433,17 @@ public class Hash<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>, IDi
347 433
348 public bool Move(TKey key_old, TKey key_new) 434 public bool Move(TKey key_old, TKey key_new)
349 { 435 {
350 var nk_old = ManagedToNativeAllocRef(key_old); 436 IntPtr gchnko = CopyNativeObject(key_old, ForceRefKey<TKey>());
351 var nk_new = ManagedToNativeAllocRef(key_new, true); 437 IntPtr nko = GetNativePtr<TKey>(gchnko, ForceRefKey<TKey>());
352 var r = eina_hash_move(Handle, nk_old, nk_new); 438 IntPtr gchnk = CopyNativeObject(key_new, ForceRefKey<TKey>());
353 NativeFreeRef<TKey>(nk_old, OwnKey && r); 439 IntPtr nk = GetNativePtr<TKey>(gchnk, ForceRefKey<TKey>());
354 NativeFreeRef<TKey>(nk_new, !r); 440 // var nk_old = ManagedToNativeAllocRef(key_old);
441 // var nk_new = ManagedToNativeAllocRef(key_new, true);
442 var r = eina_hash_move(Handle, nko, nk);
443 FreeNativeIndirection<TKey>(gchnko, ForceRefKey<TKey>());
444 FreeNativeIndirection<TKey>(gchnk, ForceRefKey<TKey>());
445 // NativeFreeRef<TKey>(nk_old, OwnKey && r);
446 // NativeFreeRef<TKey>(nk_new, !r);
355 return r; 447 return r;
356 } 448 }
357 449
@@ -383,7 +475,8 @@ public class Hash<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>, IDi
383 for (IntPtr tuplePtr; eina_iterator_next(itr, out tuplePtr);) 475 for (IntPtr tuplePtr; eina_iterator_next(itr, out tuplePtr);)
384 { 476 {
385 var tuple = Marshal.PtrToStructure<Eina.HashTupleNative>(tuplePtr); 477 var tuple = Marshal.PtrToStructure<Eina.HashTupleNative>(tuplePtr);
386 var key = NativeToManagedRef<TKey>(tuple.key); 478 IntPtr ikey = IndirectNative<TKey>(tuple.key, ForceRefKey<TKey>());
479 var key = NativeToManaged<TKey>(ikey);
387 var val = NativeToManaged<TValue>(tuple.data); 480 var val = NativeToManaged<TValue>(tuple.data);
388 yield return new KeyValuePair<TKey, TValue>(key, val); 481 yield return new KeyValuePair<TKey, TValue>(key, val);
389 } 482 }
diff --git a/src/bindings/mono/eina_mono/eina_inarray.cs b/src/bindings/mono/eina_mono/eina_inarray.cs
index d81f2ad..a99acc8 100644
--- a/src/bindings/mono/eina_mono/eina_inarray.cs
+++ b/src/bindings/mono/eina_mono/eina_inarray.cs
@@ -193,11 +193,17 @@ public class Inarray<T> : IEnumerable<T>, IDisposable
193 193
194 public int Push(T val) 194 public int Push(T val)
195 { 195 {
196 IntPtr ele = ManagedToNativeAllocInplace(val); 196 IntPtr ele = IntPtr.Zero;
197 var r = eina_inarray_push(Handle, ele); 197 GCHandle gch = GCHandle.Alloc(ele, GCHandleType.Pinned);
198 IntPtr ind = gch.AddrOfPinnedObject();
199
200 ManagedToNativeCopyTo(val, ind);
201
202 var r = eina_inarray_push(Handle, ind);
198 if (r == -1) 203 if (r == -1)
199 NativeFreeInplace<T>(ele); 204 NativeFreeInplace<T>(ele);
200 ResidueFreeInplace<T>(ele); 205 ResidueFreeInplace<T>(ele);
206 gch.Free();
201 return r; 207 return r;
202 } 208 }
203 209
@@ -230,8 +236,13 @@ public class Inarray<T> : IEnumerable<T>, IDisposable
230 236
231 public bool InsertAt(uint idx, T val) 237 public bool InsertAt(uint idx, T val)
232 { 238 {
233 IntPtr ele = ManagedToNativeAllocInplace(val); 239 IntPtr ele = IntPtr.Zero;
234 var r = eina_inarray_insert_at(Handle, idx, ele); 240 GCHandle gch = GCHandle.Alloc(ele, GCHandleType.Pinned);
241 IntPtr ind = gch.AddrOfPinnedObject();
242
243 ManagedToNativeCopyTo(val, ind);
244
245 var r = eina_inarray_insert_at(Handle, idx, ind);
235 if (!r) 246 if (!r)
236 NativeFreeInplace<T>(ele); 247 NativeFreeInplace<T>(ele);
237 ResidueFreeInplace<T>(ele); 248 ResidueFreeInplace<T>(ele);
@@ -245,8 +256,13 @@ public class Inarray<T> : IEnumerable<T>, IDisposable
245 return false; 256 return false;
246 if (OwnContent) 257 if (OwnContent)
247 NativeFreeInplace<T>(old); 258 NativeFreeInplace<T>(old);
248 var ele = ManagedToNativeAllocInplace(val); 259 var ele = IntPtr.Zero;
249 var r = eina_inarray_replace_at(Handle, idx, ele); 260 GCHandle gch = GCHandle.Alloc(ele, GCHandleType.Pinned);
261 IntPtr ind = gch.AddrOfPinnedObject();
262
263 ManagedToNativeCopyTo(val, ind);
264
265 var r = eina_inarray_replace_at(Handle, idx, ind);
250 ResidueFreeInplace<T>(ele); 266 ResidueFreeInplace<T>(ele);
251 return r; 267 return r;
252 } 268 }
diff --git a/src/bindings/mono/eina_mono/eina_value.cs b/src/bindings/mono/eina_mono/eina_value.cs
index 6fae14b..edb1ab7 100644
--- a/src/bindings/mono/eina_mono/eina_value.cs
+++ b/src/bindings/mono/eina_mono/eina_value.cs
@@ -178,7 +178,47 @@ static internal class UnsafeNativeMethods {
178 178
179 [DllImport(efl.Libs.CustomExports)] 179 [DllImport(efl.Libs.CustomExports)]
180 [return: MarshalAsAttribute(UnmanagedType.U1)] 180 [return: MarshalAsAttribute(UnmanagedType.U1)]
181 internal static extern bool eina_value_array_append_wrapper(IntPtr handle, IntPtr data); 181 internal static extern bool eina_value_container_append_wrapper_string(IntPtr handle, string data);
182
183 [DllImport(efl.Libs.CustomExports)]
184 [return: MarshalAsAttribute(UnmanagedType.U1)]
185 internal static extern bool eina_value_container_append_wrapper_char(IntPtr handle, sbyte data);
186
187 [DllImport(efl.Libs.CustomExports)]
188 [return: MarshalAsAttribute(UnmanagedType.U1)]
189 internal static extern bool eina_value_container_append_wrapper_uchar(IntPtr handle, byte data);
190
191 [DllImport(efl.Libs.CustomExports)]
192 [return: MarshalAsAttribute(UnmanagedType.U1)]
193 internal static extern bool eina_value_container_append_wrapper_short(IntPtr handle, short data);
194
195 [DllImport(efl.Libs.CustomExports)]
196 [return: MarshalAsAttribute(UnmanagedType.U1)]
197 internal static extern bool eina_value_container_append_wrapper_ushort(IntPtr handle, ushort data);
198
199 [DllImport(efl.Libs.CustomExports)]
200 [return: MarshalAsAttribute(UnmanagedType.U1)]
201 internal static extern bool eina_value_container_append_wrapper_int(IntPtr handle, int data);
202
203 [DllImport(efl.Libs.CustomExports)]
204 [return: MarshalAsAttribute(UnmanagedType.U1)]
205 internal static extern bool eina_value_container_append_wrapper_uint(IntPtr handle, uint data);
206
207 [DllImport(efl.Libs.CustomExports)]
208 [return: MarshalAsAttribute(UnmanagedType.U1)]
209 internal static extern bool eina_value_container_append_wrapper_long(IntPtr handle, long data);
210
211 [DllImport(efl.Libs.CustomExports)]
212 [return: MarshalAsAttribute(UnmanagedType.U1)]
213 internal static extern bool eina_value_container_append_wrapper_ulong(IntPtr handle, ulong data);
214
215 [DllImport(efl.Libs.CustomExports)]
216 [return: MarshalAsAttribute(UnmanagedType.U1)]
217 internal static extern bool eina_value_container_append_wrapper_float(IntPtr handle, float data);
218
219 [DllImport(efl.Libs.CustomExports)]
220 [return: MarshalAsAttribute(UnmanagedType.U1)]
221 internal static extern bool eina_value_container_append_wrapper_double(IntPtr handle, double data);
182 222
183 [DllImport(efl.Libs.CustomExports)] 223 [DllImport(efl.Libs.CustomExports)]
184 [return: MarshalAsAttribute(UnmanagedType.U1)] 224 [return: MarshalAsAttribute(UnmanagedType.U1)]
@@ -186,7 +226,47 @@ static internal class UnsafeNativeMethods {
186 226
187 [DllImport(efl.Libs.CustomExports)] 227 [DllImport(efl.Libs.CustomExports)]
188 [return: MarshalAsAttribute(UnmanagedType.U1)] 228 [return: MarshalAsAttribute(UnmanagedType.U1)]
189 internal static extern bool eina_value_array_get_wrapper(IntPtr handle, int index, out IntPtr output); 229 internal static extern bool eina_value_container_get_wrapper(IntPtr handle, int index, out IntPtr output);
230
231 [DllImport(efl.Libs.CustomExports)]
232 [return: MarshalAsAttribute(UnmanagedType.U1)]
233 internal static extern bool eina_value_container_get_wrapper(IntPtr handle, int index, out sbyte output);
234
235 [DllImport(efl.Libs.CustomExports)]
236 [return: MarshalAsAttribute(UnmanagedType.U1)]
237 internal static extern bool eina_value_container_get_wrapper(IntPtr handle, int index, out byte output);
238
239 [DllImport(efl.Libs.CustomExports)]
240 [return: MarshalAsAttribute(UnmanagedType.U1)]
241 internal static extern bool eina_value_container_get_wrapper(IntPtr handle, int index, out short output);
242
243 [DllImport(efl.Libs.CustomExports)]
244 [return: MarshalAsAttribute(UnmanagedType.U1)]
245 internal static extern bool eina_value_container_get_wrapper(IntPtr handle, int index, out ushort output);
246
247 [DllImport(efl.Libs.CustomExports)]
248 [return: MarshalAsAttribute(UnmanagedType.U1)]
249 internal static extern bool eina_value_container_get_wrapper(IntPtr handle, int index, out int output);
250
251 [DllImport(efl.Libs.CustomExports)]
252 [return: MarshalAsAttribute(UnmanagedType.U1)]
253 internal static extern bool eina_value_container_get_wrapper(IntPtr handle, int index, out uint output);
254
255 [DllImport(efl.Libs.CustomExports)]
256 [return: MarshalAsAttribute(UnmanagedType.U1)]
257 internal static extern bool eina_value_container_get_wrapper(IntPtr handle, int index, out long output);
258
259 [DllImport(efl.Libs.CustomExports)]
260 [return: MarshalAsAttribute(UnmanagedType.U1)]
261 internal static extern bool eina_value_container_get_wrapper(IntPtr handle, int index, out ulong output);
262
263 [DllImport(efl.Libs.CustomExports)]
264 [return: MarshalAsAttribute(UnmanagedType.U1)]
265 internal static extern bool eina_value_container_get_wrapper(IntPtr handle, int index, out float output);
266
267 [DllImport(efl.Libs.CustomExports)]
268 [return: MarshalAsAttribute(UnmanagedType.U1)]
269 internal static extern bool eina_value_container_get_wrapper(IntPtr handle, int index, out double output);
190 270
191 [DllImport(efl.Libs.CustomExports)] 271 [DllImport(efl.Libs.CustomExports)]
192 [return: MarshalAsAttribute(UnmanagedType.U1)] 272 [return: MarshalAsAttribute(UnmanagedType.U1)]
@@ -194,11 +274,47 @@ static internal class UnsafeNativeMethods {
194 274
195 [DllImport(efl.Libs.CustomExports)] 275 [DllImport(efl.Libs.CustomExports)]
196 [return: MarshalAsAttribute(UnmanagedType.U1)] 276 [return: MarshalAsAttribute(UnmanagedType.U1)]
197 internal static extern bool eina_value_array_set_wrapper(IntPtr handle, int index, IntPtr value); 277 internal static extern bool eina_value_container_set_wrapper_string(IntPtr handle, int index, string value);
198 278
199 [DllImport(efl.Libs.CustomExports)] 279 [DllImport(efl.Libs.CustomExports)]
200 [return: MarshalAsAttribute(UnmanagedType.U1)] 280 [return: MarshalAsAttribute(UnmanagedType.U1)]
201 internal static extern bool eina_value_list_set_wrapper(IntPtr handle, int index, IntPtr value); 281 internal static extern bool eina_value_container_set_wrapper_uchar(IntPtr handle, int index, byte value);
282
283 [DllImport(efl.Libs.CustomExports)]
284 [return: MarshalAsAttribute(UnmanagedType.U1)]
285 internal static extern bool eina_value_container_set_wrapper_char(IntPtr handle, int index, sbyte value);
286
287 [DllImport(efl.Libs.CustomExports)]
288 [return: MarshalAsAttribute(UnmanagedType.U1)]
289 internal static extern bool eina_value_container_set_wrapper_short(IntPtr handle, int index, short value);
290
291 [DllImport(efl.Libs.CustomExports)]
292 [return: MarshalAsAttribute(UnmanagedType.U1)]
293 internal static extern bool eina_value_container_set_wrapper_ushort(IntPtr handle, int index, ushort value);
294
295 [DllImport(efl.Libs.CustomExports)]
296 [return: MarshalAsAttribute(UnmanagedType.U1)]
297 internal static extern bool eina_value_container_set_wrapper_int(IntPtr handle, int index, int value);
298
299 [DllImport(efl.Libs.CustomExports)]
300 [return: MarshalAsAttribute(UnmanagedType.U1)]
301 internal static extern bool eina_value_container_set_wrapper_uint(IntPtr handle, int index, uint value);
302
303 [DllImport(efl.Libs.CustomExports)]
304 [return: MarshalAsAttribute(UnmanagedType.U1)]
305 internal static extern bool eina_value_container_set_wrapper_long(IntPtr handle, int index, long value);
306
307 [DllImport(efl.Libs.CustomExports)]
308 [return: MarshalAsAttribute(UnmanagedType.U1)]
309 internal static extern bool eina_value_container_set_wrapper_ulong(IntPtr handle, int index, ulong value);
310
311 [DllImport(efl.Libs.CustomExports)]
312 [return: MarshalAsAttribute(UnmanagedType.U1)]
313 internal static extern bool eina_value_container_set_wrapper_float(IntPtr handle, int index, float value);
314
315 [DllImport(efl.Libs.CustomExports)]
316 [return: MarshalAsAttribute(UnmanagedType.U1)]
317 internal static extern bool eina_value_container_set_wrapper_double(IntPtr handle, int index, double value);
202 318
203 [DllImport(efl.Libs.CustomExports)] 319 [DllImport(efl.Libs.CustomExports)]
204 internal static extern IntPtr eina_value_array_subtype_get_wrapper(IntPtr handle); 320 internal static extern IntPtr eina_value_array_subtype_get_wrapper(IntPtr handle);
@@ -1747,13 +1863,70 @@ public class Value : IDisposable, IComparable<Value>, IEquatable<Value>
1747 } 1863 }
1748 public bool Append(object o) { 1864 public bool Append(object o) {
1749 ContainerSanityChecks(); 1865 ContainerSanityChecks();
1750 using (DisposableIntPtr marshalled_value = MarshalValue(o)) { 1866
1751 switch (GetValueType()) { 1867 switch (GetValueSubType()) {
1752 case ValueType.Array: 1868 case ValueType.SByte:
1753 return eina_value_array_append_wrapper(this.Handle, marshalled_value.Handle); 1869 {
1754 case ValueType.List: 1870 sbyte b = Convert.ToSByte(o);
1755 return eina_value_list_append_wrapper(this.Handle, marshalled_value.Handle); 1871 return eina_value_container_append_wrapper_char(this.Handle, b);
1756 } 1872 }
1873 case ValueType.Byte:
1874 {
1875 byte b = Convert.ToByte(o);
1876 return eina_value_container_append_wrapper_uchar(this.Handle, b);
1877 }
1878
1879 case ValueType.Short:
1880 {
1881 short b = Convert.ToInt16(o);
1882 return eina_value_container_append_wrapper_short(this.Handle, b);
1883 }
1884 case ValueType.UShort:
1885 {
1886 ushort b = Convert.ToUInt16(o);
1887 return eina_value_container_append_wrapper_ushort(this.Handle, b);
1888 }
1889
1890 case ValueType.Int32:
1891 {
1892 int x = Convert.ToInt32(o);
1893 return eina_value_container_append_wrapper_int(this.Handle, x);
1894 }
1895 case ValueType.UInt32:
1896 {
1897 uint x = Convert.ToUInt32(o);
1898 return eina_value_container_append_wrapper_uint(this.Handle, x);
1899 }
1900
1901 case ValueType.Long:
1902 case ValueType.Int64:
1903 {
1904 long x = Convert.ToInt64(o);
1905 return eina_value_container_append_wrapper_long(this.Handle, x);
1906 }
1907 case ValueType.ULong:
1908 case ValueType.UInt64:
1909 {
1910 ulong x = Convert.ToUInt64(o);
1911 return eina_value_container_append_wrapper_ulong(this.Handle, x);
1912 }
1913
1914 case ValueType.Float:
1915 {
1916 float x = Convert.ToSingle(o);
1917 return eina_value_container_append_wrapper_float(this.Handle, x);
1918 }
1919 case ValueType.Double:
1920 {
1921 double x = Convert.ToDouble(o);
1922 return eina_value_container_append_wrapper_double(this.Handle, x);
1923 }
1924
1925 case ValueType.String:
1926 {
1927 string x = Convert.ToString(o);
1928 return eina_value_container_append_wrapper_string(this.Handle, x);
1929 }
1757 } 1930 }
1758 return false; 1931 return false;
1759 } 1932 }
@@ -1763,49 +1936,163 @@ public class Value : IDisposable, IComparable<Value>, IEquatable<Value>
1763 get { 1936 get {
1764 ContainerSanityChecks(i); 1937 ContainerSanityChecks(i);
1765 1938
1766 IntPtr output = IntPtr.Zero; 1939 switch (GetValueSubType()) {
1767 switch (GetValueType()) { 1940 case ValueType.SByte:
1768 case ValueType.Array: 1941 {
1769 if (!eina_value_array_get_wrapper(this.Handle, i, out output)) 1942 sbyte ret = default(sbyte);
1770 return null; 1943 eina_value_container_get_wrapper(this.Handle, i, out ret);
1771 break; 1944 return ret;
1772 case ValueType.List: 1945 }
1773 if (!eina_value_list_get_wrapper(this.Handle, i, out output)) 1946 case ValueType.Byte:
1774 return null; 1947 {
1775 break; 1948 byte ret = default(byte);
1949 eina_value_container_get_wrapper(this.Handle, i, out ret);
1950 return ret;
1951 }
1952
1953 case ValueType.Short:
1954 {
1955 short ret = default(short);
1956 eina_value_container_get_wrapper(this.Handle, i, out ret);
1957 return ret;
1958 }
1959 case ValueType.UShort:
1960 {
1961 ushort ret = default(ushort);
1962 eina_value_container_get_wrapper(this.Handle, i, out ret);
1963 return ret;
1964 }
1965
1966 case ValueType.Int32:
1967 {
1968 int ret = default(int);
1969 eina_value_container_get_wrapper(this.Handle, i, out ret);
1970 return ret;
1971 }
1972 case ValueType.UInt32:
1973 {
1974 uint ret = default(uint);
1975 eina_value_container_get_wrapper(this.Handle, i, out ret);
1976 return ret;
1977 }
1978
1979 case ValueType.Long:
1980 case ValueType.Int64:
1981 {
1982 long ret = default(long);
1983 eina_value_container_get_wrapper(this.Handle, i, out ret);
1984 return ret;
1985 }
1986 case ValueType.ULong:
1987 case ValueType.UInt64:
1988 {
1989 ulong ret = default(ulong);
1990 eina_value_container_get_wrapper(this.Handle, i, out ret);
1991 return ret;
1992 }
1993
1994 case ValueType.Float:
1995 {
1996 float ret = default(float);
1997 eina_value_container_get_wrapper(this.Handle, i, out ret);
1998 return ret;
1999 }
2000 case ValueType.Double:
2001 {
2002 double ret = default(double);
2003 eina_value_container_get_wrapper(this.Handle, i, out ret);
2004 return ret;
2005 }
2006
2007 case ValueType.String:
2008 {
2009 // Using intptr as using string as the arg type in the DllImport'd function would
2010 // make mono take ownership of the string.
2011 IntPtr ptr = IntPtr.Zero;
2012 eina_value_container_get_wrapper(this.Handle, i, out ptr);
2013 return Eina.StringConversion.NativeUtf8ToManagedString(ptr);
2014 }
2015 default:
2016 throw new InvalidOperationException("Subtype not supported.");
1776 } 2017 }
1777 return UnMarshalPtr(output);
1778 } 2018 }
1779 set { 2019 set {
1780 ContainerSanityChecks(i); 2020 ContainerSanityChecks(i);
1781 2021
1782 switch (GetValueType()) { 2022 switch (GetValueSubType()) {
1783 case ValueType.Array: 2023 case ValueType.SByte:
1784 ArraySet(i, value); 2024 {
2025 sbyte v = Convert.ToSByte(value);
2026 eina_value_container_set_wrapper_char(this.Handle, i, v);
2027 }
1785 break; 2028 break;
1786 case ValueType.List: 2029 case ValueType.Byte:
1787 ListSet(i, value); 2030 {
2031 byte v = Convert.ToByte(value);
2032 eina_value_container_set_wrapper_uchar(this.Handle, i, v);
2033 }
1788 break; 2034 break;
1789 }
1790 }
1791 }
1792 2035
1793 private void ArraySet(int i, object value) { 2036 case ValueType.Short:
1794 using (DisposableIntPtr marshalled_value = MarshalValue(value)) 2037 {
1795 { 2038 short x = Convert.ToInt16(value);
1796 if (!eina_value_array_set_wrapper(this.Handle, i, 2039 eina_value_container_set_wrapper_short(this.Handle, i, x);
1797 marshalled_value.Handle)) { 2040 }
1798 throw new SetItemFailedException($"Failed to set item at index {i}"); 2041 break;
1799 } 2042 case ValueType.UShort:
1800 } 2043 {
1801 } 2044 ushort x = Convert.ToUInt16(value);
2045 eina_value_container_set_wrapper_ushort(this.Handle, i, x);
2046 }
2047 break;
1802 2048
1803 private void ListSet(int i, object value) { 2049 case ValueType.Int32:
1804 using (DisposableIntPtr marshalled_value = MarshalValue(value)) 2050 {
1805 { 2051 int x = Convert.ToInt32(value);
1806 if (!eina_value_list_set_wrapper(this.Handle, i, 2052 eina_value_container_set_wrapper_int(this.Handle, i, x);
1807 marshalled_value.Handle)) { 2053 }
1808 throw new SetItemFailedException($"Failed to set item at index {i}"); 2054 break;
2055 case ValueType.UInt32:
2056 {
2057 uint x = Convert.ToUInt32(value);
2058 eina_value_container_set_wrapper_uint(this.Handle, i, x);
2059 }
2060 break;
2061
2062 case ValueType.Long:
2063 case ValueType.Int64:
2064 {
2065 long x = Convert.ToInt64(value);
2066 eina_value_container_set_wrapper_long(this.Handle, i, x);
2067 }
2068 break;
2069 case ValueType.ULong:
2070 case ValueType.UInt64:
2071 {
2072 ulong x = Convert.ToUInt64(value);
2073 eina_value_container_set_wrapper_ulong(this.Handle, i, x);
2074 }
2075 break;
2076
2077 case ValueType.Float:
2078 {
2079 float x = Convert.ToSingle(value);
2080 eina_value_container_set_wrapper_float(this.Handle, i, x);
2081 }
2082 break;
2083 case ValueType.Double:
2084 {
2085 double x = Convert.ToDouble(value);
2086 eina_value_container_set_wrapper_double(this.Handle, i, x);
2087 }
2088 break;
2089
2090 case ValueType.String:
2091 {
2092 string x = Convert.ToString(value);
2093 eina_value_container_set_wrapper_string(this.Handle, i, x);
2094 }
2095 break;
1809 } 2096 }
1810 } 2097 }
1811 } 2098 }
@@ -1826,54 +2113,6 @@ public class Value : IDisposable, IComparable<Value>, IEquatable<Value>
1826 } 2113 }
1827 return ValueTypeBridge.GetManaged(native_subtype); 2114 return ValueTypeBridge.GetManaged(native_subtype);
1828 } 2115 }
1829
1830 private DisposableIntPtr MarshalValue(object value)
1831 {
1832 IntPtr ret = IntPtr.Zero;
1833 bool shouldFree = false;
1834 switch(GetValueSubType()) {
1835 case ValueType.Int32:
1836 {
1837 int x = Convert.ToInt32(value);
1838 ret = new IntPtr(x);
1839 }
1840 break;
1841 case ValueType.UInt32:
1842 {
1843 uint x = Convert.ToUInt32(value);
1844 ret = new IntPtr((int)x);
1845 }
1846 break;
1847 case ValueType.String:
1848 {
1849 string x = value as string;
1850 if (x == null)
1851 ret = IntPtr.Zero;
1852 else {
1853 ret = StringConversion.ManagedStringToNativeUtf8Alloc(x);
1854 shouldFree = true;
1855 }
1856 }
1857 break;
1858 }
1859
1860 return new DisposableIntPtr(ret, shouldFree);
1861 }
1862
1863 private object UnMarshalPtr(IntPtr data)
1864 {
1865 switch(GetValueSubType()) {
1866 case ValueType.Int32:
1867 return Convert.ToInt32(data.ToInt32());
1868 case ValueType.UInt32:
1869 return Convert.ToUInt32(data.ToInt32());
1870 case ValueType.String:
1871 return StringConversion.NativeUtf8ToManagedString(data);
1872 default:
1873 return null;
1874 }
1875 }
1876
1877} 2116}
1878 2117
1879/// <summary> Custom marshaler to convert value pointers to managed values and back, 2118/// <summary> Custom marshaler to convert value pointers to managed values and back,
diff --git a/src/bindings/mono/eldbus_mono/eldbus_connection.cs b/src/bindings/mono/eldbus_mono/eldbus_connection.cs
index 099582e..bef7f29 100644
--- a/src/bindings/mono/eldbus_mono/eldbus_connection.cs
+++ b/src/bindings/mono/eldbus_mono/eldbus_connection.cs
@@ -205,7 +205,7 @@ public class Connection : IDisposable
205 var ptr = eldbus_connection_unique_name_get(Handle); 205 var ptr = eldbus_connection_unique_name_get(Handle);
206 if (ptr == IntPtr.Zero) 206 if (ptr == IntPtr.Zero)
207 return null; 207 return null;
208 return Marshal.PtrToStringAuto(ptr); 208 return Eina.StringConversion.NativeUtf8ToManagedString(ptr);
209 } 209 }
210 210
211 public eldbus.Pending NameRequest(string bus, uint flags, eldbus.MessageDelegate dlgt = null) 211 public eldbus.Pending NameRequest(string bus, uint flags, eldbus.MessageDelegate dlgt = null)
diff --git a/src/bindings/mono/eldbus_mono/eldbus_message.cs b/src/bindings/mono/eldbus_mono/eldbus_message.cs
index b3826d6..a8c96ff 100644
--- a/src/bindings/mono/eldbus_mono/eldbus_message.cs
+++ b/src/bindings/mono/eldbus_mono/eldbus_message.cs
@@ -279,42 +279,42 @@ public class Message : IDisposable
279 { 279 {
280 CheckHandle(); 280 CheckHandle();
281 var ptr = eldbus_message_path_get(Handle); 281 var ptr = eldbus_message_path_get(Handle);
282 return Marshal.PtrToStringAuto(ptr); 282 return Eina.StringConversion.NativeUtf8ToManagedString(ptr);
283 } 283 }
284 284
285 public string GetInterface() 285 public string GetInterface()
286 { 286 {
287 CheckHandle(); 287 CheckHandle();
288 var ptr = eldbus_message_interface_get(Handle); 288 var ptr = eldbus_message_interface_get(Handle);
289 return Marshal.PtrToStringAuto(ptr); 289 return Eina.StringConversion.NativeUtf8ToManagedString(ptr);
290 } 290 }
291 291
292 public string GetMember() 292 public string GetMember()
293 { 293 {
294 CheckHandle(); 294 CheckHandle();
295 var ptr = eldbus_message_member_get(Handle); 295 var ptr = eldbus_message_member_get(Handle);
296 return Marshal.PtrToStringAuto(ptr); 296 return Eina.StringConversion.NativeUtf8ToManagedString(ptr);
297 } 297 }
298 298
299 public string GetDestination() 299 public string GetDestination()
300 { 300 {
301 CheckHandle(); 301 CheckHandle();
302 var ptr = eldbus_message_destination_get(Handle); 302 var ptr = eldbus_message_destination_get(Handle);
303 return Marshal.PtrToStringAuto(ptr); 303 return Eina.StringConversion.NativeUtf8ToManagedString(ptr);
304 } 304 }
305 305
306 public string GetSender() 306 public string GetSender()
307 { 307 {
308 CheckHandle(); 308 CheckHandle();
309 var ptr = eldbus_message_sender_get(Handle); 309 var ptr = eldbus_message_sender_get(Handle);
310 return Marshal.PtrToStringAuto(ptr); 310 return Eina.StringConversion.NativeUtf8ToManagedString(ptr);
311 } 311 }
312 312
313 public string GetSignature() 313 public string GetSignature()
314 { 314 {
315 CheckHandle(); 315 CheckHandle();
316 var ptr = eldbus_message_signature_get(Handle); 316 var ptr = eldbus_message_signature_get(Handle);
317 return Marshal.PtrToStringAuto(ptr); 317 return Eina.StringConversion.NativeUtf8ToManagedString(ptr);
318 } 318 }
319 319
320 public eldbus.Message NewError(string error_name, string error_msg) 320 public eldbus.Message NewError(string error_name, string error_msg)
@@ -341,8 +341,8 @@ public class Message : IDisposable
341 IntPtr name_ptr; 341 IntPtr name_ptr;
342 IntPtr text_ptr; 342 IntPtr text_ptr;
343 bool r = eldbus_message_error_get(Handle, out name_ptr, out text_ptr); 343 bool r = eldbus_message_error_get(Handle, out name_ptr, out text_ptr);
344 name = Marshal.PtrToStringAuto(name_ptr); 344 name = Eina.StringConversion.NativeUtf8ToManagedString(name_ptr);
345 text = Marshal.PtrToStringAuto(text_ptr); 345 text = Eina.StringConversion.NativeUtf8ToManagedString(text_ptr);
346 return r; 346 return r;
347 } 347 }
348 348
@@ -408,7 +408,7 @@ public class Message : IDisposable
408 CheckHandle(); 408 CheckHandle();
409 IntPtr aux; 409 IntPtr aux;
410 var r = eldbus_message_arguments_get(Handle, Argument.StringType.Signature, out aux); 410 var r = eldbus_message_arguments_get(Handle, Argument.StringType.Signature, out aux);
411 val = Marshal.PtrToStringAuto(aux); 411 val = Eina.StringConversion.NativeUtf8ToManagedString(aux);
412 return r; 412 return r;
413 } 413 }
414 414
@@ -417,7 +417,7 @@ public class Message : IDisposable
417 CheckHandle(); 417 CheckHandle();
418 IntPtr aux; 418 IntPtr aux;
419 var r = eldbus_message_arguments_get(Handle, Argument.ObjectPathType.Signature, out aux); 419 var r = eldbus_message_arguments_get(Handle, Argument.ObjectPathType.Signature, out aux);
420 val = Marshal.PtrToStringAuto(aux); 420 val = Eina.StringConversion.NativeUtf8ToManagedString(aux);
421 return r; 421 return r;
422 } 422 }
423 423
@@ -426,7 +426,7 @@ public class Message : IDisposable
426 CheckHandle(); 426 CheckHandle();
427 IntPtr aux; 427 IntPtr aux;
428 var r = eldbus_message_arguments_get(Handle, Argument.SignatureType.Signature, out aux); 428 var r = eldbus_message_arguments_get(Handle, Argument.SignatureType.Signature, out aux);
429 val = Marshal.PtrToStringAuto(aux); 429 val = Eina.StringConversion.NativeUtf8ToManagedString(aux);
430 return r; 430 return r;
431 } 431 }
432 432
@@ -617,7 +617,7 @@ public class MessageIterator
617 CheckHandle(); 617 CheckHandle();
618 IntPtr aux; 618 IntPtr aux;
619 bool r = eldbus_message_iter_get_and_next(Handle, Argument.StringType.Code, out aux); 619 bool r = eldbus_message_iter_get_and_next(Handle, Argument.StringType.Code, out aux);
620 val = Marshal.PtrToStringAuto(aux); 620 val = Eina.StringConversion.NativeUtf8ToManagedString(aux);
621 return r; 621 return r;
622 } 622 }
623 623
@@ -626,7 +626,7 @@ public class MessageIterator
626 CheckHandle(); 626 CheckHandle();
627 IntPtr aux; 627 IntPtr aux;
628 bool r = eldbus_message_iter_get_and_next(Handle, Argument.ObjectPathType.Code, out aux); 628 bool r = eldbus_message_iter_get_and_next(Handle, Argument.ObjectPathType.Code, out aux);
629 val = Marshal.PtrToStringAuto(aux); 629 val = Eina.StringConversion.NativeUtf8ToManagedString(aux);
630 return r; 630 return r;
631 } 631 }
632 632
@@ -635,7 +635,7 @@ public class MessageIterator
635 CheckHandle(); 635 CheckHandle();
636 IntPtr aux; 636 IntPtr aux;
637 bool r = eldbus_message_iter_get_and_next(Handle, Argument.SignatureType.Code, out aux); 637 bool r = eldbus_message_iter_get_and_next(Handle, Argument.SignatureType.Code, out aux);
638 val = Marshal.PtrToStringAuto(aux); 638 val = Eina.StringConversion.NativeUtf8ToManagedString(aux);
639 return r; 639 return r;
640 } 640 }
641 641
@@ -732,7 +732,7 @@ public class MessageIterator
732 CheckHandle(); 732 CheckHandle();
733 IntPtr aux; 733 IntPtr aux;
734 eldbus_message_iter_basic_get(Handle, out aux); 734 eldbus_message_iter_basic_get(Handle, out aux);
735 val = Marshal.PtrToStringAuto(aux); 735 val = Eina.StringConversion.NativeUtf8ToManagedString(aux);
736 } 736 }
737 737
738 public void Get(out eldbus.ObjectPath val) 738 public void Get(out eldbus.ObjectPath val)
@@ -740,7 +740,7 @@ public class MessageIterator
740 CheckHandle(); 740 CheckHandle();
741 IntPtr aux; 741 IntPtr aux;
742 eldbus_message_iter_basic_get(Handle, out aux); 742 eldbus_message_iter_basic_get(Handle, out aux);
743 val = Marshal.PtrToStringAuto(aux); 743 val = Eina.StringConversion.NativeUtf8ToManagedString(aux);
744 } 744 }
745 745
746 public void Get(out eldbus.SignatureString val) 746 public void Get(out eldbus.SignatureString val)
@@ -748,7 +748,7 @@ public class MessageIterator
748 CheckHandle(); 748 CheckHandle();
749 IntPtr aux; 749 IntPtr aux;
750 eldbus_message_iter_basic_get(Handle, out aux); 750 eldbus_message_iter_basic_get(Handle, out aux);
751 val = Marshal.PtrToStringAuto(aux); 751 val = Eina.StringConversion.NativeUtf8ToManagedString(aux);
752 } 752 }
753 753
754 public void Get(out eldbus.UnixFd val) 754 public void Get(out eldbus.UnixFd val)
diff --git a/src/bindings/mono/eldbus_mono/eldbus_object.cs b/src/bindings/mono/eldbus_mono/eldbus_object.cs
index 4488853..7b48743 100644
--- a/src/bindings/mono/eldbus_mono/eldbus_object.cs
+++ b/src/bindings/mono/eldbus_mono/eldbus_object.cs
@@ -175,14 +175,14 @@ public class Object : System.IDisposable
175 { 175 {
176 CheckHandle(); 176 CheckHandle();
177 var ptr = eldbus_object_bus_name_get(Handle); 177 var ptr = eldbus_object_bus_name_get(Handle);
178 return Marshal.PtrToStringAuto(ptr); 178 return Eina.StringConversion.NativeUtf8ToManagedString(ptr);
179 } 179 }
180 180
181 public string GetPath() 181 public string GetPath()
182 { 182 {
183 CheckHandle(); 183 CheckHandle();
184 var ptr = eldbus_object_path_get(Handle); 184 var ptr = eldbus_object_path_get(Handle);
185 return Marshal.PtrToStringAuto(ptr); 185 return Eina.StringConversion.NativeUtf8ToManagedString(ptr);
186 } 186 }
187 187
188 public void Ref() 188 public void Ref()
diff --git a/src/bindings/mono/eldbus_mono/eldbus_pending.cs b/src/bindings/mono/eldbus_mono/eldbus_pending.cs
index f5afa05..906630e 100644
--- a/src/bindings/mono/eldbus_mono/eldbus_pending.cs
+++ b/src/bindings/mono/eldbus_mono/eldbus_pending.cs
@@ -82,28 +82,28 @@ public class Pending
82 { 82 {
83 CheckHandle(); 83 CheckHandle();
84 var ptr = eldbus_pending_destination_get(Handle); 84 var ptr = eldbus_pending_destination_get(Handle);
85 return Marshal.PtrToStringAuto(ptr); 85 return Eina.StringConversion.NativeUtf8ToManagedString(ptr);
86 } 86 }
87 87
88 public string GetPath() 88 public string GetPath()
89 { 89 {
90 CheckHandle(); 90 CheckHandle();
91 var ptr = eldbus_pending_path_get(Handle); 91 var ptr = eldbus_pending_path_get(Handle);
92 return Marshal.PtrToStringAuto(ptr); 92 return Eina.StringConversion.NativeUtf8ToManagedString(ptr);
93 } 93 }
94 94
95 public string GetInterface() 95 public string GetInterface()
96 { 96 {
97 CheckHandle(); 97 CheckHandle();
98 var ptr = eldbus_pending_interface_get(Handle); 98 var ptr = eldbus_pending_interface_get(Handle);
99 return Marshal.PtrToStringAuto(ptr); 99 return Eina.StringConversion.NativeUtf8ToManagedString(ptr);
100 } 100 }
101 101
102 public string GetMethod() 102 public string GetMethod()
103 { 103 {
104 CheckHandle(); 104 CheckHandle();
105 var ptr = eldbus_pending_method_get(Handle); 105 var ptr = eldbus_pending_method_get(Handle);
106 return Marshal.PtrToStringAuto(ptr); 106 return Eina.StringConversion.NativeUtf8ToManagedString(ptr);
107 } 107 }
108} 108}
109 109
diff --git a/src/bindings/mono/eldbus_mono/eldbus_proxy.cs b/src/bindings/mono/eldbus_mono/eldbus_proxy.cs
index fa34ce3..ea44ca5 100644
--- a/src/bindings/mono/eldbus_mono/eldbus_proxy.cs
+++ b/src/bindings/mono/eldbus_mono/eldbus_proxy.cs
@@ -141,7 +141,7 @@ public class Proxy : IDisposable
141 { 141 {
142 CheckHandle(); 142 CheckHandle();
143 var ptr = eldbus_proxy_interface_get(Handle); 143 var ptr = eldbus_proxy_interface_get(Handle);
144 return Marshal.PtrToStringAuto(ptr); 144 return Eina.StringConversion.NativeUtf8ToManagedString(ptr);
145 } 145 }
146 146
147 eldbus.Message NewMethodCall(string member) 147 eldbus.Message NewMethodCall(string member)
diff --git a/src/bindings/mono/eo_mono/FunctionWrapper.cs b/src/bindings/mono/eo_mono/FunctionWrapper.cs
new file mode 100644
index 0000000..03e8138
--- /dev/null
+++ b/src/bindings/mono/eo_mono/FunctionWrapper.cs
@@ -0,0 +1,97 @@
1using System;
2using System.Runtime.InteropServices;
3
4namespace Efl { namespace Eo {
5
6public partial class FunctionInterop
7{
8 public static IntPtr LoadFunctionPointer(string moduleName, string functionName)
9 {
10 NativeModule module = new NativeModule(moduleName);
11 Eina.Log.Debug($"searching {module.Module} for {functionName}");
12 var s = FunctionInterop.dlsym(module.Module, functionName);
13 Eina.Log.Debug($"searching {module.Module} for{functionName}, result {s}");
14 return s;
15 }
16 public static IntPtr LoadFunctionPointer(string functionName)
17 {
18 Eina.Log.Debug($"searching {null} for {functionName}");
19 var s = FunctionInterop.dlsym(IntPtr.Zero, functionName);
20 Eina.Log.Debug($"searching {null} for {functionName}, result {s}");
21 return s;
22 }
23}
24
25public class FunctionWrapper<T>
26{
27 private Lazy<FunctionLoadResult<T>> loadResult;
28#pragma warning disable 0414
29 private NativeModule module; // so it doesn't get unloaded
30#pragma warning restore 0414
31
32 private static FunctionLoadResult<T> LazyInitialization(NativeModule module, string functionName)
33 {
34 if (module.Module == IntPtr.Zero)
35 return new FunctionLoadResult<T>(FunctionLoadResultKind.LibraryNotFound);
36 else
37 {
38 IntPtr funcptr = FunctionInterop.LoadFunctionPointer(module.Module, functionName);
39 if (funcptr == IntPtr.Zero)
40 return new FunctionLoadResult<T>(FunctionLoadResultKind.FunctionNotFound);
41 else
42 return new FunctionLoadResult<T>(Marshal.GetDelegateForFunctionPointer<T>(funcptr));
43 }
44 }
45
46 public FunctionWrapper(string moduleName, string functionName)
47 : this (new NativeModule(moduleName), functionName)
48 {
49 }
50
51 public FunctionWrapper(NativeModule module, string functionName)
52 {
53 this.module = module;
54 loadResult = new Lazy<FunctionLoadResult<T>>
55 (() =>
56 {
57 return LazyInitialization(module, functionName);
58 });
59 }
60
61 public FunctionLoadResult<T> Value
62 {
63 get
64 {
65 return loadResult.Value;
66 }
67 }
68}
69
70public enum FunctionLoadResultKind { Success, LibraryNotFound, FunctionNotFound }
71
72public class FunctionLoadResult<T>
73{
74 public FunctionLoadResultKind Kind;
75 public T _Delegate;
76 public T Delegate
77 {
78 get {
79 if (_Delegate == null)
80 throw new InvalidOperationException($"Trying to get Delegate while not loaded. Load result: {Kind}");
81 return _Delegate;
82 }
83 }
84
85 public FunctionLoadResult(FunctionLoadResultKind kind)
86 {
87 this.Kind = kind;
88 }
89 public FunctionLoadResult(T Delegate)
90 {
91 this._Delegate = Delegate;
92 this.Kind = FunctionLoadResultKind.Success;
93 }
94}
95
96
97} }
diff --git a/src/bindings/mono/eo_mono/FunctionWrapper_Unix.cs b/src/bindings/mono/eo_mono/FunctionWrapper_Unix.cs
new file mode 100644
index 0000000..76ee489
--- /dev/null
+++ b/src/bindings/mono/eo_mono/FunctionWrapper_Unix.cs
@@ -0,0 +1,21 @@
1using System;
2using System.Runtime.InteropServices;
3
4namespace Efl { namespace Eo {
5
6public partial class FunctionInterop
7{
8 [DllImport(efl.Libs.Libdl)]
9 public static extern IntPtr dlsym(IntPtr handle, string symbol);
10
11 public static IntPtr LoadFunctionPointer(IntPtr nativeLibraryHandle, string functionName)
12 {
13 Eina.Log.Debug("searching {nativeLibraryHandle} for {functionName}");
14 var s = FunctionInterop.dlsym(nativeLibraryHandle, functionName);
15 Eina.Log.Debug("searching {nativeLibraryHandle} for {functionName}, result {s}");
16 return s;
17 }
18}
19
20
21} }
diff --git a/src/bindings/mono/eo_mono/FunctionWrapper_Windows.cs b/src/bindings/mono/eo_mono/FunctionWrapper_Windows.cs
new file mode 100644
index 0000000..3cdd80c
--- /dev/null
+++ b/src/bindings/mono/eo_mono/FunctionWrapper_Windows.cs
@@ -0,0 +1,15 @@
1using System;
2using System.Runtime.InteropServices;
3
4namespace Efl { namespace Eo {
5
6public partial class FunctionInterop
7{
8 [DllImport(efl.Libs.Libdl)]
9 public static extern IntPtr GetProcAddress(IntPtr handle, string symbol);
10
11 private static IntPtr LoadFunctionPointer(IntPtr nativeLibraryHandle, string functionName)
12 => FunctionInterop.GetProcAddress(nativeLibraryHandle, functionName);
13}
14
15} }
diff --git a/src/bindings/mono/eo_mono/NativeModule.cs b/src/bindings/mono/eo_mono/NativeModule.cs
new file mode 100644
index 0000000..324a933
--- /dev/null
+++ b/src/bindings/mono/eo_mono/NativeModule.cs
@@ -0,0 +1,33 @@
1using System;
2
3namespace Efl { namespace Eo {
4
5public partial class NativeModule : IDisposable
6{
7 private Lazy<IntPtr> module;
8
9 public NativeModule(string libName)
10 {
11 module = new Lazy<IntPtr>
12 (() =>
13 {
14 return LoadLibrary(libName);
15 });
16 }
17
18 public IntPtr Module
19 {
20 get
21 {
22 return module.Value;
23 }
24 }
25
26 public void Dispose()
27 {
28 UnloadLibrary(module.Value);
29 module = null;
30 }
31}
32
33} }
diff --git a/src/bindings/mono/eo_mono/NativeModule_Unix.cs b/src/bindings/mono/eo_mono/NativeModule_Unix.cs
new file mode 100644
index 0000000..6f69395
--- /dev/null
+++ b/src/bindings/mono/eo_mono/NativeModule_Unix.cs
@@ -0,0 +1,46 @@
1using System;
2using System.Runtime.InteropServices;
3
4namespace Efl { namespace Eo {
5
6public partial class NativeModule
7{
8 public const int RTLD_NOW = 0x002;
9 // Currently we are using GLOBAL due to issues
10 // with the way evas modules are built.
11 public const int RTLD_GLOBAL = 0x100;
12
13 [DllImport(efl.Libs.Libdl)]
14 public static extern IntPtr dlopen(string fileName, int flag);
15 [DllImport(efl.Libs.Libdl)]
16 public static extern int dlclose(IntPtr handle);
17
18 public static void UnloadLibrary(IntPtr handle)
19 {
20 dlclose(handle);
21 }
22
23 public static IntPtr LoadLibrary(string filename)
24 {
25 Eina.Log.Debug($"Loading library {filename}");
26 var r = dlopen(filename, RTLD_NOW | RTLD_GLOBAL);
27 if (r == IntPtr.Zero)
28 {
29 r = dlopen("lib" + filename, RTLD_NOW | RTLD_GLOBAL);
30 if (r == IntPtr.Zero)
31 {
32 r = dlopen(filename + ".so", RTLD_NOW | RTLD_GLOBAL);
33 if (r == IntPtr.Zero)
34 {
35 r = dlopen("lib" + filename + ".so", RTLD_NOW | RTLD_GLOBAL);
36 }
37 }
38 }
39 return r;
40 }
41}
42
43
44
45
46} }
diff --git a/src/bindings/mono/eo_mono/NativeModule_Windows.cs b/src/bindings/mono/eo_mono/NativeModule_Windows.cs
new file mode 100644
index 0000000..889adc0
--- /dev/null
+++ b/src/bindings/mono/eo_mono/NativeModule_Windows.cs
@@ -0,0 +1,15 @@
1using System;
2using System.Runtime.InteropServices;
3
4namespace Efl { namespace Eo {
5
6public class partial NativeModule
7{
8 [DllImport(efl.Libs.Kernel32, CharSet = CharSet.Unicode, SetLastError = true)]
9 public static extern IntPtr LoadLibrary(string libFilename);
10}
11
12
13
14
15} }
diff --git a/src/bindings/mono/eo_mono/iwrapper.cs b/src/bindings/mono/eo_mono/iwrapper.cs
index 16acf6a..7444215 100644
--- a/src/bindings/mono/eo_mono/iwrapper.cs
+++ b/src/bindings/mono/eo_mono/iwrapper.cs
@@ -12,19 +12,42 @@ using EoG = Efl.Eo.Globals;
12namespace Efl { namespace Eo { 12namespace Efl { namespace Eo {
13 13
14public class Globals { 14public class Globals {
15 [DllImport(efl.Libs.Eo)] public static extern void efl_object_init(); 15 [return: MarshalAs(UnmanagedType.U1)]
16 [DllImport(efl.Libs.Eo)] public static extern void efl_object_shutdown(); 16 public delegate bool efl_object_init_delegate();
17 public static FunctionWrapper<efl_object_init_delegate> efl_object_init_ptr =
18 new FunctionWrapper<efl_object_init_delegate>(efl.Libs.EoModule, "efl_object_init");
19 public static bool efl_object_init() => efl_object_init_ptr.Value.Delegate();
20
21 public delegate void efl_object_shutdown_delegate();
22 public static FunctionWrapper<efl_object_shutdown_delegate> efl_object_shutdown_ptr = new FunctionWrapper<efl_object_shutdown_delegate>(efl.Libs.EoModule, "efl_object_shutdown");
23 public static void efl_object_shutdown() => efl_object_shutdown_ptr.Value.Delegate();
24 // [DllImport(efl.Libs.Eo)] public static extern void efl_object_shutdown();
25 public static FunctionWrapper<_efl_add_internal_start_delegate> _efl_add_internal_start_ptr = new FunctionWrapper<_efl_add_internal_start_delegate>(efl.Libs.EoModule, "_efl_add_internal_start");
26 public delegate IntPtr
27 _efl_add_internal_start_delegate([MarshalAs(UnmanagedType.LPStr)] String file, int line,
28 IntPtr klass, IntPtr parent, byte is_ref, byte is_fallback);
17 [DllImport(efl.Libs.Eo)] public static extern IntPtr 29 [DllImport(efl.Libs.Eo)] public static extern IntPtr
18 _efl_add_internal_start([MarshalAs(UnmanagedType.LPStr)] String file, int line, 30 _efl_add_internal_start([MarshalAs(UnmanagedType.LPStr)] String file, int line,
19 IntPtr klass, IntPtr parent, byte is_ref, byte is_fallback); 31 IntPtr klass, IntPtr parent, byte is_ref, byte is_fallback);
32 public delegate IntPtr
33 _efl_add_end_delegate(IntPtr eo, byte is_ref, byte is_fallback);
20 [DllImport(efl.Libs.Eo)] public static extern IntPtr 34 [DllImport(efl.Libs.Eo)] public static extern IntPtr
21 _efl_add_end(IntPtr eo, byte is_ref, byte is_fallback); 35 _efl_add_end(IntPtr eo, byte is_ref, byte is_fallback);
36 public delegate IntPtr
37 efl_ref_delegate(IntPtr eo);
22 [DllImport(efl.Libs.Eo)] public static extern IntPtr 38 [DllImport(efl.Libs.Eo)] public static extern IntPtr
23 efl_ref(IntPtr eo); 39 efl_ref(IntPtr eo);
40 public delegate void
41 efl_unref_delegate(IntPtr eo);
24 [DllImport(efl.Libs.CustomExports)] public static extern void 42 [DllImport(efl.Libs.CustomExports)] public static extern void
25 efl_unref(IntPtr eo); 43 efl_unref(IntPtr eo);
44 public delegate int
45 efl_ref_count_delegate(IntPtr eo);
26 [DllImport(efl.Libs.Eo)] public static extern int 46 [DllImport(efl.Libs.Eo)] public static extern int
27 efl_ref_count(IntPtr eo); 47 efl_ref_count(IntPtr eo);
48
49 [DllImport(efl.Libs.Eo)] public static extern IntPtr
50 efl_class_name_get(IntPtr eo);
28 [DllImport(efl.Libs.Eo)] public static extern IntPtr 51 [DllImport(efl.Libs.Eo)] public static extern IntPtr
29 efl_class_new(IntPtr class_description, IntPtr parent, IntPtr term); 52 efl_class_new(IntPtr class_description, IntPtr parent, IntPtr term);
30 [DllImport(efl.Libs.Eo)] public static extern IntPtr 53 [DllImport(efl.Libs.Eo)] public static extern IntPtr
@@ -123,36 +146,45 @@ public class Globals {
123 efl_class_new(IntPtr class_description, IntPtr parent, IntPtr extn1, IntPtr extn2, IntPtr extn3, IntPtr extn4, IntPtr extn5, IntPtr extn6, IntPtr extn7, IntPtr extn8, IntPtr extn9, IntPtr extn10, IntPtr extn11, IntPtr extn12, IntPtr extn13, IntPtr extn14, IntPtr extn15, IntPtr extn16, IntPtr extn17, IntPtr extn18, IntPtr extn19, IntPtr extn20, IntPtr extn21, IntPtr extn22, IntPtr extn23, IntPtr extn24, IntPtr extn25, IntPtr extn26, IntPtr extn27, IntPtr extn28, IntPtr extn29, IntPtr extn30, IntPtr extn31, IntPtr extn32, IntPtr extn33, IntPtr extn34, IntPtr extn35, IntPtr extn36, IntPtr extn37, IntPtr extn38, IntPtr extn39, IntPtr extn40, IntPtr extn41, IntPtr extn42, IntPtr extn43, IntPtr extn44, IntPtr extn45, IntPtr extn46, IntPtr extn47, IntPtr term); 146 efl_class_new(IntPtr class_description, IntPtr parent, IntPtr extn1, IntPtr extn2, IntPtr extn3, IntPtr extn4, IntPtr extn5, IntPtr extn6, IntPtr extn7, IntPtr extn8, IntPtr extn9, IntPtr extn10, IntPtr extn11, IntPtr extn12, IntPtr extn13, IntPtr extn14, IntPtr extn15, IntPtr extn16, IntPtr extn17, IntPtr extn18, IntPtr extn19, IntPtr extn20, IntPtr extn21, IntPtr extn22, IntPtr extn23, IntPtr extn24, IntPtr extn25, IntPtr extn26, IntPtr extn27, IntPtr extn28, IntPtr extn29, IntPtr extn30, IntPtr extn31, IntPtr extn32, IntPtr extn33, IntPtr extn34, IntPtr extn35, IntPtr extn36, IntPtr extn37, IntPtr extn38, IntPtr extn39, IntPtr extn40, IntPtr extn41, IntPtr extn42, IntPtr extn43, IntPtr extn44, IntPtr extn45, IntPtr extn46, IntPtr extn47, IntPtr term);
124 [DllImport(efl.Libs.Eo)] public static extern IntPtr 147 [DllImport(efl.Libs.Eo)] public static extern IntPtr
125 efl_class_new(IntPtr class_description, IntPtr parent, IntPtr extn1, IntPtr extn2, IntPtr extn3, IntPtr extn4, IntPtr extn5, IntPtr extn6, IntPtr extn7, IntPtr extn8, IntPtr extn9, IntPtr extn10, IntPtr extn11, IntPtr extn12, IntPtr extn13, IntPtr extn14, IntPtr extn15, IntPtr extn16, IntPtr extn17, IntPtr extn18, IntPtr extn19, IntPtr extn20, IntPtr extn21, IntPtr extn22, IntPtr extn23, IntPtr extn24, IntPtr extn25, IntPtr extn26, IntPtr extn27, IntPtr extn28, IntPtr extn29, IntPtr extn30, IntPtr extn31, IntPtr extn32, IntPtr extn33, IntPtr extn34, IntPtr extn35, IntPtr extn36, IntPtr extn37, IntPtr extn38, IntPtr extn39, IntPtr extn40, IntPtr extn41, IntPtr extn42, IntPtr extn43, IntPtr extn44, IntPtr extn45, IntPtr extn46, IntPtr extn47, IntPtr extn48, IntPtr term); 148 efl_class_new(IntPtr class_description, IntPtr parent, IntPtr extn1, IntPtr extn2, IntPtr extn3, IntPtr extn4, IntPtr extn5, IntPtr extn6, IntPtr extn7, IntPtr extn8, IntPtr extn9, IntPtr extn10, IntPtr extn11, IntPtr extn12, IntPtr extn13, IntPtr extn14, IntPtr extn15, IntPtr extn16, IntPtr extn17, IntPtr extn18, IntPtr extn19, IntPtr extn20, IntPtr extn21, IntPtr extn22, IntPtr extn23, IntPtr extn24, IntPtr extn25, IntPtr extn26, IntPtr extn27, IntPtr extn28, IntPtr extn29, IntPtr extn30, IntPtr extn31, IntPtr extn32, IntPtr extn33, IntPtr extn34, IntPtr extn35, IntPtr extn36, IntPtr extn37, IntPtr extn38, IntPtr extn39, IntPtr extn40, IntPtr extn41, IntPtr extn42, IntPtr extn43, IntPtr extn44, IntPtr extn45, IntPtr extn46, IntPtr extn47, IntPtr extn48, IntPtr term);
126 [DllImport(efl.Libs.Eo)] public static extern byte efl_class_functions_set(IntPtr klass_id, IntPtr object_ops, IntPtr class_ops, IntPtr reflection_ops); 149
150 public delegate byte efl_class_functions_set_delegate(IntPtr klass_id, IntPtr object_ops, IntPtr class_ops);
151 [DllImport(efl.Libs.Eo)] public static extern byte efl_class_functions_set(IntPtr klass_id, IntPtr object_ops, IntPtr class_ops);
152 public delegate IntPtr efl_data_scope_get_delegate(IntPtr obj, IntPtr klass);
127 [DllImport(efl.Libs.Eo)] public static extern IntPtr efl_data_scope_get(IntPtr obj, IntPtr klass); 153 [DllImport(efl.Libs.Eo)] public static extern IntPtr efl_data_scope_get(IntPtr obj, IntPtr klass);
154 public delegate IntPtr efl_super_delegate(IntPtr obj, IntPtr klass);
128 [DllImport(efl.Libs.Eo)] public static extern IntPtr efl_super(IntPtr obj, IntPtr klass); 155 [DllImport(efl.Libs.Eo)] public static extern IntPtr efl_super(IntPtr obj, IntPtr klass);
156 public delegate IntPtr efl_class_get_delegate(IntPtr obj);
129 [DllImport(efl.Libs.Eo)] public static extern IntPtr efl_class_get(IntPtr obj); 157 [DllImport(efl.Libs.Eo)] public static extern IntPtr efl_class_get(IntPtr obj);
130#if WIN32 158 public delegate IntPtr dlerror_delegate();
131 public static IntPtr RTLD_DEFAULT = new IntPtr(1);
132#else
133 public static IntPtr RTLD_DEFAULT = new IntPtr(0);
134#endif
135 [DllImport(efl.Libs.Evil)] public static extern IntPtr dlerror(); 159 [DllImport(efl.Libs.Evil)] public static extern IntPtr dlerror();
136 [DllImport(efl.Libs.Evil)] public static extern IntPtr dlsym
137 (IntPtr handle, [MarshalAs(UnmanagedType.LPStr)] String name);
138 160
139 [DllImport(efl.Libs.Eo)] public static extern bool efl_event_callback_priority_add( 161 public delegate bool efl_event_callback_priority_add_delegate(
162 System.IntPtr obj,
163 IntPtr desc,
164 short priority,
165 Efl.EventCb cb,
166 System.IntPtr data);
167 [DllImport(efl.Libs.Eo)] public static extern bool efl_event_callback_priority_add(
140 System.IntPtr obj, 168 System.IntPtr obj,
141 IntPtr desc, 169 IntPtr desc,
142 short priority, 170 short priority,
143 Efl.EventCb cb, 171 Efl.EventCb cb,
144 System.IntPtr data); 172 System.IntPtr data);
145 [DllImport(efl.Libs.Eo)] public static extern bool efl_event_callback_del( 173 public delegate bool efl_event_callback_del_delegate(
146 System.IntPtr obj, 174 System.IntPtr obj,
147 IntPtr desc, 175 IntPtr desc,
148 Efl.EventCb cb, 176 Efl.EventCb cb,
149 System.IntPtr data); 177 System.IntPtr data);
178 [DllImport(efl.Libs.Eo)] public static extern bool efl_event_callback_del(
179 System.IntPtr obj,
180 IntPtr desc,
181 Efl.EventCb cb,
182 System.IntPtr data);
183 public delegate IntPtr
184 efl_object_legacy_only_event_description_get_delegate([MarshalAs(UnmanagedType.LPStr)] String name);
150 [DllImport(efl.Libs.Eo)] public static extern IntPtr 185 [DllImport(efl.Libs.Eo)] public static extern IntPtr
151 efl_object_legacy_only_event_description_get([MarshalAs(UnmanagedType.LPStr)] String name); 186 efl_object_legacy_only_event_description_get([MarshalAs(UnmanagedType.LPStr)] String name);
152 187
153 public static System.Collections.Concurrent.ConcurrentDictionary<System.Type, System.IntPtr> klasses
154 = new System.Collections.Concurrent.ConcurrentDictionary<System.Type, System.IntPtr>();
155
156 public const int RTLD_NOW = 2; 188 public const int RTLD_NOW = 2;
157 189
158 public delegate byte class_initializer(IntPtr klass); 190 public delegate byte class_initializer(IntPtr klass);
@@ -241,7 +273,7 @@ public class Globals {
241 } 273 }
242 public static byte class_initializer_call(IntPtr klass, System.Type type) 274 public static byte class_initializer_call(IntPtr klass, System.Type type)
243 { 275 {
244 Eina.Log.Debug($"called with 0x{klass.ToInt64()} {type}"); 276 Eina.Log.Debug($"called with 0x{klass.ToInt64():x} {type}");
245 Efl.Eo.NativeClass nativeClass = get_native_class(type.BaseType); 277 Efl.Eo.NativeClass nativeClass = get_native_class(type.BaseType);
246 278
247 if (nativeClass != null) 279 if (nativeClass != null)
@@ -260,7 +292,7 @@ public class Globals {
260 if(nc != null) 292 if(nc != null)
261 { 293 {
262 var moredescs = nc.GetEoOps(type); 294 var moredescs = nc.GetEoOps(type);
263 Eina.Log.Debug("adding {moredescs.Count} more descs to registration"); 295 Eina.Log.Debug($"adding {moredescs.Count} more descs to registration");
264 descs.AddRange(moredescs); 296 descs.AddRange(moredescs);
265 count = descs.Count; 297 count = descs.Count;
266 } 298 }
@@ -279,7 +311,7 @@ public class Globals {
279 ops.count = (UIntPtr)count; 311 ops.count = (UIntPtr)count;
280 IntPtr ops_ptr = Marshal.AllocHGlobal(Marshal.SizeOf(ops)); 312 IntPtr ops_ptr = Marshal.AllocHGlobal(Marshal.SizeOf(ops));
281 Marshal.StructureToPtr(ops, ops_ptr, false); 313 Marshal.StructureToPtr(ops, ops_ptr, false);
282 Efl.Eo.Globals.efl_class_functions_set(klass, ops_ptr, IntPtr.Zero, IntPtr.Zero); 314 Efl.Eo.Globals.efl_class_functions_set(klass, ops_ptr, IntPtr.Zero);
283 //EoKlass = klass; 315 //EoKlass = klass;
284 } 316 }
285 else 317 else
@@ -392,38 +424,6 @@ public class Globals {
392 return null; 424 return null;
393 } 425 }
394 426
395 public static IntPtr cached_string_to_intptr(Dictionary<String, IntPtr> dict, String str)
396 {
397 IntPtr ptr = IntPtr.Zero;
398
399 if (str == null)
400 return ptr;
401
402 if (!dict.TryGetValue(str, out ptr))
403 {
404 ptr = Eina.StringConversion.ManagedStringToNativeUtf8Alloc(str);
405 dict[str] = ptr;
406 }
407
408 return ptr;
409 }
410
411 public static IntPtr cached_stringshare_to_intptr(Dictionary<String, IntPtr> dict, String str)
412 {
413 IntPtr ptr = IntPtr.Zero;
414
415 if (str == null)
416 return ptr;
417
418 if (!dict.TryGetValue(str, out ptr))
419 {
420 ptr = Eina.Stringshare.eina_stringshare_add(str);
421 dict[str] = ptr;
422 }
423
424 return ptr;
425 }
426
427 public static void free_dict_values(Dictionary<String, IntPtr> dict) 427 public static void free_dict_values(Dictionary<String, IntPtr> dict)
428 { 428 {
429 foreach(IntPtr ptr in dict.Values) 429 foreach(IntPtr ptr in dict.Values)
@@ -529,6 +529,120 @@ public interface IWrapper
529 } 529 }
530} 530}
531 531
532public static class ClassRegister
533{
534 public static System.Type GetManagedType(IntPtr klass)
535 {
536 System.Type t;
537 if (Efl.Eo.ClassRegister.typeFromKlass.TryGetValue(klass, out t))
538 return t;
539
540 // If it isn't on the dictionary then it is a Native binding class
541 IntPtr namePtr = Efl.Eo.Globals.efl_class_name_get(klass);
542 if (namePtr == IntPtr.Zero) {
543 throw new System.InvalidOperationException($"Could not get Native class name. Handle: {klass}");
544 }
545
546 string name = Eina.StringConversion.NativeUtf8ToManagedString(namePtr)
547 .Replace("_", ""); // Convert Efl C name to C# name
548
549 var curr_asm = typeof(IWrapper).Assembly;
550 t = curr_asm.GetType(name);
551 if (t == null)
552 {
553 foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
554 {
555 if (assembly == curr_asm)
556 continue;
557
558 t = assembly.GetType(name);
559 if (t != null)
560 break;
561 }
562 if (t == null) {
563 throw new System.InvalidOperationException($"Could not find the C# binding class for the EFL class: {name}");
564 }
565 }
566 AddToKlassTypeBiDictionary(klass, t); // Cache it in the dictionary
567 return t;
568 }
569
570 public static IntPtr GetKlass(System.Type objectType)
571 {
572 IntPtr klass;
573 if (klassFromType.TryGetValue(objectType, out klass))
574 return klass;
575
576 // Check if it is a Native binding class
577 klass = GetNativeKlassPtr(objectType);
578 if (klass != IntPtr.Zero) {
579 // Add to the dictionary cache
580 AddToKlassTypeBiDictionary(klass, objectType);
581 return klass;
582 }
583
584 // Unregistered Inherited class, let's register it
585 IntPtr baseKlass = GetNativeBaseKlassPtr(objectType);
586 if (baseKlass == IntPtr.Zero)
587 throw new System.InvalidOperationException($"Could not get base C# binding class for Inherited type: {objectType.FullName}");
588 return RegisterKlass(baseKlass, objectType);
589 }
590
591 public static IntPtr GetInheritKlassOrRegister(IntPtr baseKlass, System.Type objectType)
592 {
593 IntPtr klass;
594 if (klassFromType.TryGetValue(objectType, out klass))
595 return klass;
596
597 return RegisterKlass(baseKlass, objectType);
598 }
599
600 private static IntPtr RegisterKlass(IntPtr baseKlass, System.Type objectType)
601 {
602 lock (klassAllocLock) {
603 IntPtr newKlass = Efl.Eo.Globals.register_class(objectType.FullName, baseKlass, objectType);
604 if (newKlass == IntPtr.Zero) {
605 throw new System.InvalidOperationException($"Failed to register class '{objectType.FullName}'");
606 }
607 AddToKlassTypeBiDictionary(newKlass, objectType);
608 return newKlass;
609 }
610 }
611
612 private static IntPtr GetNativeBaseKlassPtr(System.Type objectType)
613 {
614 for (System.Type t = objectType.BaseType; t != null; t = t.BaseType)
615 {
616 var method = t.GetMethod("GetEflClassStatic",
617 System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
618 if (method != null)
619 return (IntPtr) method.Invoke(null, null);
620 }
621 throw new System.InvalidOperationException($"Class '{objectType.FullName}' is not an Efl object");
622 }
623
624 private static IntPtr GetNativeKlassPtr(System.Type objectType)
625 {
626 var method = objectType.GetMethod("GetEflClassStatic",
627 System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
628 return (IntPtr) method?.Invoke(null, null);
629 }
630
631 public static void AddToKlassTypeBiDictionary(IntPtr klassPtr, System.Type objectType)
632 {
633 klassFromType[objectType] = klassPtr;
634 typeFromKlass[klassPtr] = objectType;
635 }
636
637 public static System.Collections.Concurrent.ConcurrentDictionary<System.Type, System.IntPtr> klassFromType
638 = new System.Collections.Concurrent.ConcurrentDictionary<System.Type, System.IntPtr>();
639
640 public static System.Collections.Concurrent.ConcurrentDictionary<System.IntPtr, System.Type> typeFromKlass
641 = new System.Collections.Concurrent.ConcurrentDictionary<System.IntPtr, System.Type>();
642
643 private static readonly object klassAllocLock = new object();
644}
645
532public interface IOwnershipTag 646public interface IOwnershipTag
533{ 647{
534} 648}
@@ -587,6 +701,46 @@ public class MarshalTest<T, U> : ICustomMarshaler
587 } 701 }
588} 702}
589 703
704///<summary>Marshals between System.Type instances and Eo classes (IntPtrs).</summary>
705public class MarshalEflClass : ICustomMarshaler
706{
707 public static ICustomMarshaler GetInstance(string cookie)
708 {
709 Eina.Log.Debug("MarshalTest.GetInstance cookie " + cookie);
710 return new MarshalEflClass();
711 }
712 public void CleanUpManagedData(object ManagedObj)
713 {
714 }
715
716 public void CleanUpNativeData(IntPtr pNativeData)
717 {
718 }
719
720 public int GetNativeDataSize()
721 {
722 Eina.Log.Debug("MarshalTest.GetNativeDataSize");
723 return 0;
724 }
725
726 public IntPtr MarshalManagedToNative(object ManagedObj)
727 {
728 Eina.Log.Debug("MarshalTest.MarshallManagedToNative");
729 if (ManagedObj == null)
730 return IntPtr.Zero;
731 var t = (System.Type) ManagedObj;
732 return Efl.Eo.ClassRegister.GetKlass(t);
733 }
734
735 public object MarshalNativeToManaged(IntPtr pNativeData)
736 {
737 Eina.Log.Debug("MarshalTest.MarshalNativeToManaged");
738 if (pNativeData == IntPtr.Zero)
739 return null;
740 return Efl.Eo.ClassRegister.GetManagedType(pNativeData);
741 }
742}
743
590public class StringPassOwnershipMarshaler : ICustomMarshaler { 744public class StringPassOwnershipMarshaler : ICustomMarshaler {
591 public object MarshalNativeToManaged(IntPtr pNativeData) { 745 public object MarshalNativeToManaged(IntPtr pNativeData) {
592 var ret = Eina.StringConversion.NativeUtf8ToManagedString(pNativeData); 746 var ret = Eina.StringConversion.NativeUtf8ToManagedString(pNativeData);
diff --git a/src/bindings/mono/eo_mono/meson.build b/src/bindings/mono/eo_mono/meson.build
index 4fbdf51..8aca400 100644
--- a/src/bindings/mono/eo_mono/meson.build
+++ b/src/bindings/mono/eo_mono/meson.build
@@ -1,4 +1,12 @@
1mono_files += files( 1mono_files += files(
2 'iwrapper.cs', 2 'iwrapper.cs',
3 'workaround.cs' 3 'workaround.cs',
4 'FunctionWrapper.cs',
5 'NativeModule.cs'
4) 6)
7
8if host_machine.system() == 'windows'
9 mono_files += files('FunctionWrapper_Windows.cs', 'NativeModule_Windows.cs')
10else
11 mono_files += files('FunctionWrapper_Unix.cs', 'NativeModule_Unix.cs')
12endif
diff --git a/src/bindings/mono/eo_mono/workaround.cs b/src/bindings/mono/eo_mono/workaround.cs
index 99fb53b..4d57677 100644
--- a/src/bindings/mono/eo_mono/workaround.cs
+++ b/src/bindings/mono/eo_mono/workaround.cs
@@ -80,19 +80,19 @@ public struct EventDescription {
80 80
81 private static Dictionary<string, IntPtr> descriptions = new Dictionary<string, IntPtr>(); 81 private static Dictionary<string, IntPtr> descriptions = new Dictionary<string, IntPtr>();
82 82
83 public EventDescription(string name) 83 public EventDescription(string module, string name)
84 { 84 {
85 this.Name = GetNative(name); 85 this.Name = GetNative(module, name);
86 this.Unfreezable = false; 86 this.Unfreezable = false;
87 this.Legacy_is = false; 87 this.Legacy_is = false;
88 this.Restart = false; 88 this.Restart = false;
89 } 89 }
90 90
91 public static IntPtr GetNative(string name) 91 public static IntPtr GetNative(string module, string name)
92 { 92 {
93 if (!descriptions.ContainsKey(name)) 93 if (!descriptions.ContainsKey(name))
94 { 94 {
95 IntPtr data = Efl.Eo.Globals.dlsym(Efl.Eo.Globals.RTLD_DEFAULT, name); 95 IntPtr data = Efl.Eo.FunctionInterop.LoadFunctionPointer(module, name);
96 96
97 if (data == IntPtr.Zero) { 97 if (data == IntPtr.Zero) {
98 string error = Eina.StringConversion.NativeUtf8ToManagedString(Efl.Eo.Globals.dlerror()); 98 string error = Eina.StringConversion.NativeUtf8ToManagedString(Efl.Eo.Globals.dlerror());
diff --git a/src/bindings/mono/meson.build b/src/bindings/mono/meson.build
index b9d6879..4f04a01 100644
--- a/src/bindings/mono/meson.build
+++ b/src/bindings/mono/meson.build
@@ -1,5 +1,33 @@
1add_languages('cs') 1add_languages('cs')
2 2
3
4runtime_assemblies = []
5
6# Check if we should use dotnet options
7cs_is_dotnet = meson.get_compiler('cs').get_id().contains('dotnet')
8
9if (cs_is_dotnet)
10
11warning('Dotnet support is still not upstream in meson.')
12
13runtime_assemblies += [
14 '-r:System.Console.dll',
15 '-r:Microsoft.CSharp.dll',
16 '-r:System.Collections.dll',
17 '-r:System.Collections.Concurrent.dll',
18 '-r:System.ComponentModel.Primitives.dll',
19 '-r:System.ComponentModel.Primitives.dll',
20 '-r:System.Diagnostics.Debug.dll',
21 '-r:System.Diagnostics.TraceSource.dll',
22 '-r:System.Dynamic.Runtime.dll',
23 '-r:System.Linq.dll',
24 '-r:System.Runtime.dll',
25 '-r:System.Runtime.Extensions.dll',
26 '-r:System.Security.dll',
27]
28
29endif
30
3mono_sublibs = [ 31mono_sublibs = [
4 ['Eina', true, ], # 32 ['Eina', true, ], #
5 ['Eolian', true, ], # 33 ['Eolian', true, ], #
@@ -9,11 +37,11 @@ mono_sublibs = [
9 ['Evas', false, ], # 37 ['Evas', false, ], #
10 ['Edje', false, ], # 38 ['Edje', false, ], #
11 ['Eldbus', true, ], # 39 ['Eldbus', true, ], #
12 ['Ecore_Evas', true, ], #
13 ['Elementary', false, ] # 40 ['Elementary', false, ] #
14] 41]
15 42
16blacklisted_files = [ 43blacklisted_files = [
44 'efl_class.eo',
17 'efl_canvas_text.eo', 45 'efl_canvas_text.eo',
18 'efl_canvas_scene3d.eo', 46 'efl_canvas_scene3d.eo',
19 'evas_canvas3d_camera.eo', 47 'evas_canvas3d_camera.eo',
@@ -57,7 +85,7 @@ blacklisted_files = [
57 'elm_view_list.eo', 85 'elm_view_list.eo',
58 'elm_genlist_item.eo', 86 'elm_genlist_item.eo',
59 'elm_gengrid.eo', 87 'elm_gengrid.eo',
60 'elm_glview.eo.cs' 88 'elm_glview_eo.cs'
61] 89]
62 90
63efl_mono_lib = library('eflcustomexportsmono', 91efl_mono_lib = library('eflcustomexportsmono',
@@ -105,18 +133,6 @@ foreach lib : mono_sublibs
105 endif 133 endif
106endforeach 134endforeach
107 135
108legacy_evas_required_by_mono = ['evas_box.eo', 'evas_image.eo', 'evas_table.eo', 'evas_text.eo']
109subdir_file_location = join_paths('..', '..', 'lib', 'evas', 'canvas')
110foreach mono_gen_file : legacy_evas_required_by_mono
111 mono_generator_target += custom_target('eolian_mono_gen_'+mono_gen_file.underscorify()+'',
112 input : join_paths(subdir_file_location, mono_gen_file),
113 output : [mono_gen_file + '.cs'],
114 command : [eolian_mono_gen, beta_option, '-I', meson.current_source_dir(), eolian_include_directories,
115 '--dllimport', 'evas',
116 '-o', join_paths(meson.current_build_dir(), mono_gen_file + '.cs'),
117 '@INPUT@'])
118endforeach
119
120efl_mono_conf_data = configuration_data() 136efl_mono_conf_data = configuration_data()
121efl_mono_conf_data.set('EINA', eina_lib.full_path()) 137efl_mono_conf_data.set('EINA', eina_lib.full_path())
122efl_mono_conf_data.set('EFL', efl_lib.full_path()) 138efl_mono_conf_data.set('EFL', efl_lib.full_path())
@@ -126,14 +142,21 @@ efl_mono_conf_data.set('EVAS', evas_lib.full_path())
126efl_mono_conf_data.set('ELDBUS', eldbus_lib.full_path()) 142efl_mono_conf_data.set('ELDBUS', eldbus_lib.full_path())
127efl_mono_conf_data.set('ELEMENTARY', elementary_lib.full_path()) 143efl_mono_conf_data.set('ELEMENTARY', elementary_lib.full_path())
128 144
129configure_file(input : 'efl_mono.dll.config.in', 145efl_mono_dll_config = configure_file(input : 'efl_mono.dll.config.in',
130 output : 'efl_mono.dll.config', 146 output : 'efl_mono.dll.config',
131 configuration : efl_mono_conf_data) 147 configuration : efl_mono_conf_data)
148
149extra_cs_args = runtime_assemblies
150
151if get_option('mono-beta')
152 extra_cs_args += '-d:EFL_BETA'
153endif
132 154
133efl_mono = library('efl_mono', 155efl_mono = library('efl_mono',
134 mono_generator_target + mono_files + [efl_src], 156 mono_generator_target + mono_files + [efl_src],
135 install : true, 157 install : true,
136 install_dir : join_paths(dir_lib, 'efl-mono-'+version_major) 158 install_dir : join_paths(dir_lib, 'efl-mono-'+version_major),
159 cs_args : extra_cs_args
137) 160)
138 161
139efl_mono_test_suite_path=join_paths(meson.current_build_dir()) 162efl_mono_test_suite_path=join_paths(meson.current_build_dir())