summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFelipe Magno de Almeida <felipe@expertisesolutions.com.br>2019-01-16 16:29:56 +0900
committerVitor Sousa <vitorsousa@expertisesolutions.com.br>2019-03-01 23:58:56 -0300
commitf392c5a4363cf09e8c0e50a42c46416a09a72c74 (patch)
tree1966addc0a769679e9dfa641df816c80d243651b /src
parentdd89eb2fd1755c2816d97f28822639e03ed38608 (diff)
efl-mono: Add support for dotnet core
Summary: This commits adds dotnet as a supported C# platform for EFL# bindings. Due to differences between Mono and Dotnet regarding DllImport, the bindings now are using an imperative approach to load the function pointers through the NativeModule and FunctionWrapper classes. These classes handle the dlopen/LoadLibrary and dlsym/GetProcAddress calls. Also, the previous caching of non-owned strings returned to native code was removed until further memory checks. We also had to create workaround for bool and chars in Structs for C# marshaling. Going through System.Byte instead and Marshaling manually to their respective types. In order to actually build efl_mono.dll with dotnet right now, issue #4782 from Meson should be fixed to make it properly detect and used the Dotnet compiler. Also use "-Ddotnet=true" when running meson. Fixes T7394 Reviewers: felipealmeida, vitor.sousa, bu5hm4n Reviewed By: vitor.sousa Subscribers: cedric Tags: #efl Maniphest Tasks: T7394 Differential Revision: https://phab.enlightenment.org/D8069
Diffstat (limited to 'src')
-rw-r--r--src/Makefile_Efl_Mono.am19
-rw-r--r--src/bin/eolian_mono/eolian/mono/events.hh5
-rw-r--r--src/bin/eolian_mono/eolian/mono/function_definition.hh75
-rw-r--r--src/bin/eolian_mono/eolian/mono/function_pointer.hh8
-rw-r--r--src/bin/eolian_mono/eolian/mono/function_registration.hh7
-rw-r--r--src/bin/eolian_mono/eolian/mono/klass.hh18
-rw-r--r--src/bin/eolian_mono/eolian/mono/marshall_annotation.hh128
-rw-r--r--src/bin/eolian_mono/eolian/mono/marshall_type.hh46
-rw-r--r--src/bin/eolian_mono/eolian/mono/marshall_type_impl.hh26
-rw-r--r--src/bin/eolian_mono/eolian/mono/name_helpers.hh18
-rw-r--r--src/bin/eolian_mono/eolian/mono/parameter.hh8
-rw-r--r--src/bin/eolian_mono/eolian/mono/part_definition.hh2
-rw-r--r--src/bin/eolian_mono/eolian/mono/struct_definition.hh44
-rw-r--r--src/bindings/cxx/eina_cxx/eina_variant.hh16
-rw-r--r--src/bindings/mono/efl_mono/efl_all.cs18
-rw-r--r--src/bindings/mono/efl_mono/efl_libs.cs.in16
-rw-r--r--src/bindings/mono/eina_mono/eina_common.cs10
-rw-r--r--src/bindings/mono/eina_mono/eina_container_common.cs337
-rw-r--r--src/bindings/mono/eina_mono/eina_hash.cs151
-rw-r--r--src/bindings/mono/eina_mono/eina_inarray.cs29
-rw-r--r--src/bindings/mono/eo_mono/FunctionWrapper.cs95
-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.cs95
-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.build43
-rw-r--r--src/lib/eolian_cxx/grammar/klass_def.hpp67
-rw-r--r--src/tests/efl_mono/Eo.cs7
-rw-r--r--src/tests/efl_mono/dummy_test_object.eo4
-rw-r--r--src/tests/efl_mono/efl-mono-suite.runtimeconfig.json10
-rw-r--r--src/tests/efl_mono/libefl_mono_native_test.c5
-rw-r--r--src/tests/efl_mono/meson.build37
36 files changed, 1024 insertions, 468 deletions
diff --git a/src/Makefile_Efl_Mono.am b/src/Makefile_Efl_Mono.am
index fe8c66efd4..56c03fbf77 100644
--- a/src/Makefile_Efl_Mono.am
+++ b/src/Makefile_Efl_Mono.am
@@ -4,8 +4,25 @@ efl_custom_exports_mono_files = \
4 4
5efl_eo_mono_files = \ 5efl_eo_mono_files = \
6 bindings/mono/eo_mono/iwrapper.cs \ 6 bindings/mono/eo_mono/iwrapper.cs \
7 bindings/mono/eo_mono/FunctionWrapper.cs \
8 bindings/mono/eo_mono/NativeModule.cs \
7 bindings/mono/eo_mono/workaround.cs 9 bindings/mono/eo_mono/workaround.cs
8 10
11if HAVE_WIN32
12
13efl_eo_mono_files += \
14 bindings/mono/eo_mono/FunctionWrapper_Windows.cs \
15 bindings/mono/eo_mono/NativeModule_Windows.cs
16
17else
18
19efl_eo_mono_files += \
20 bindings/mono/eo_mono/FunctionWrapper_Unix.cs \
21 bindings/mono/eo_mono/NativeModule_Unix.cs
22
23endif
24
25
9efl_eina_mono_files = \ 26efl_eina_mono_files = \
10 bindings/mono/eina_mono/eina_config.cs \ 27 bindings/mono/eina_mono/eina_config.cs \
11 bindings/mono/eina_mono/eina_array.cs \ 28 bindings/mono/eina_mono/eina_array.cs \
@@ -293,7 +310,7 @@ msbuildcsprojs: ../libefl_mono.csproj
293 done 310 done
294 311
295### Some hard-coded runtime dependencies for tests and examples 312### Some hard-coded runtime dependencies for tests and examples
296TEST_PATHS = $(abs_top_builddir)/src/lib/efl_mono:$(abs_top_builddir)/src/lib/efl_mono/.libs:$(abs_top_builddir)/src/lib/eina/.libs:$(abs_top_builddir)/src/lib/ecore/.libs:$(abs_top_builddir)/src/lib/ecore_evas/.libs:$(abs_top_builddir)/src/lib/eo/.libs:$(abs_top_builddir)/src/lib/evas/.libs:$(abs_top_builddir)/src/lib/emile/.libs:$(abs_top_builddir)/src/lib/eet/.libs:$(abs_top_builddir)/src/lib/efl/.libs:$(abs_top_builddir)/src/ecore-file/.libs:$(abs_top_builddir)/src/lib/efl-input/.libs:$(abs_top_builddir)/src/lib/edje/.libs:$(abs_top_builddir)/src/lib/ethumb/.libs:$(abs_top_builddir)/src/lib/ethumb-client/.libs:$(abs_top_builddir)/src/lib/emotion/.libs:$(abs_top_builddir)/src/lib/ecore-imf/.libs:$(abs_top_builddir)/src/lib/ecore-con/.libs:$(abs_top_builddir)/src/lib/eldbus/.libs:$(abs_top_builddir)/src/lib/efreet/.libs:$(abs_top_builddir)/src/lib/efreet-mime/.libs:$(abs_top_builddir)/src/lib/efreet-trash/.libs:$(abs_top_builddir)/src/lib/eio/.libs:$(abs_top_builddir)/src/lib/elocation/.libs:$(abs_top_builddir)/src/lib/elementary/.libs 313TEST_PATHS = $(abs_top_builddir)/src/lib/efl_mono:$(abs_top_builddir)/src/lib/efl_mono/.libs:$(abs_top_builddir)/src/lib/eina/.libs:$(abs_top_builddir)/src/lib/ecore/.libs:$(abs_top_builddir)/src/lib/ecore_evas/.libs:$(abs_top_builddir)/src/lib/eo/.libs:$(abs_top_builddir)/src/lib/evas/.libs:$(abs_top_builddir)/src/lib/emile/.libs:$(abs_top_builddir)/src/lib/eet/.libs:$(abs_top_builddir)/src/lib/efl/.libs:$(abs_top_builddir)/src/ecore-file/.libs:$(abs_top_builddir)/src/lib/efl-input/.libs:$(abs_top_builddir)/src/lib/edje/.libs:$(abs_top_builddir)/src/lib/ethumb/.libs:$(abs_top_builddir)/src/lib/ethumb-client/.libs:$(abs_top_builddir)/src/lib/emotion/.libs:$(abs_top_builddir)/src/lib/ecore-imf/.libs:$(abs_top_builddir)/src/lib/ecore-con/.libs:$(abs_top_builddir)/src/lib/eldbus/.libs:$(abs_top_builddir)/src/lib/efreet/.libs:$(abs_top_builddir)/src/lib/efreet-mime/.libs:$(abs_top_builddir)/src/lib/efreet-trash/.libs:$(abs_top_builddir)/src/lib/eio/.libs:$(abs_top_builddir)/src/lib/elocation/.libs:$(abs_top_builddir)/src/lib/elementary/.libs:$(abs_top_builddir)/src/tests/efl_mono/.libs
297 314
298WIN_ADD_TEST_PATHS = $(abs_top_builddir)/src/lib/evil/.libs:$(abs_top_builddir)/src/lib/ecore_win32/.libs:$(abs_top_builddir)/src/lib/ector/.libs:$(abs_top_builddir)/src/lib/ecore_con/.libs:$(abs_top_builddir)/src/lib/ecore_imf/.libs:$(abs_top_builddir)/src/lib/ecore_file/.libs:$(abs_top_builddir)/src/lib/ecore_input/.libs:$(abs_top_builddir)/src/ethumb_client/.libs:$(abs_top_builddir)/src/tests/efl_mono/.libs 315WIN_ADD_TEST_PATHS = $(abs_top_builddir)/src/lib/evil/.libs:$(abs_top_builddir)/src/lib/ecore_win32/.libs:$(abs_top_builddir)/src/lib/ector/.libs:$(abs_top_builddir)/src/lib/ecore_con/.libs:$(abs_top_builddir)/src/lib/ecore_imf/.libs:$(abs_top_builddir)/src/lib/ecore_file/.libs:$(abs_top_builddir)/src/lib/ecore_input/.libs:$(abs_top_builddir)/src/ethumb_client/.libs:$(abs_top_builddir)/src/tests/efl_mono/.libs
299 316
diff --git a/src/bin/eolian_mono/eolian/mono/events.hh b/src/bin/eolian_mono/eolian/mono/events.hh
index 20225b4f41..2a2aa4c9eb 100644
--- a/src/bin/eolian_mono/eolian/mono/events.hh
+++ b/src/bin/eolian_mono/eolian/mono/events.hh
@@ -301,12 +301,15 @@ struct event_definition_generator
301 bool generate_event_add_remove(OutputIterator sink, attributes::event_def const &evt, const std::string& event_name, Context context) const 301 bool generate_event_add_remove(OutputIterator sink, attributes::event_def const &evt, const std::string& event_name, Context context) const
302 { 302 {
303 std::string upper_c_name = utils::to_uppercase(evt.c_name); 303 std::string upper_c_name = utils::to_uppercase(evt.c_name);
304 auto unit = (const Eolian_Unit*) context_find_tag<eolian_state_context>(context).state;
305 attributes::klass_def klass(get_klass(evt.klass, unit), unit);
306 auto library_name = context_find_tag<library_context>(context).actual_library_name(klass.filename);
304 return as_generator( 307 return as_generator(
305 scope_tab << "{\n" 308 scope_tab << "{\n"
306 << scope_tab << scope_tab << "add {\n" 309 << scope_tab << scope_tab << "add {\n"
307 << scope_tab << scope_tab << scope_tab << "lock (eventLock) {\n" 310 << scope_tab << scope_tab << scope_tab << "lock (eventLock) {\n"
308 << scope_tab << scope_tab << scope_tab << scope_tab << "string key = \"_" << upper_c_name << "\";\n" 311 << scope_tab << scope_tab << scope_tab << scope_tab << "string key = \"_" << upper_c_name << "\";\n"
309 << scope_tab << scope_tab << scope_tab << scope_tab << "if (add_cpp_event_handler(key, this.evt_" << event_name << "_delegate)) {\n" 312 << scope_tab << scope_tab << scope_tab << scope_tab << "if (add_cpp_event_handler(" << library_name << ", key, this.evt_" << event_name << "_delegate)) {\n"
310 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "eventHandlers.AddHandler(" << event_name << "Key , value);\n" 313 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "eventHandlers.AddHandler(" << event_name << "Key , value);\n"
311 << scope_tab << scope_tab << scope_tab << scope_tab << "} else\n" 314 << scope_tab << scope_tab << scope_tab << scope_tab << "} else\n"
312 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "Eina.Log.Error($\"Error adding proxy for event {key}\");\n" 315 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "Eina.Log.Error($\"Error adding proxy for event {key}\");\n"
diff --git a/src/bin/eolian_mono/eolian/mono/function_definition.hh b/src/bin/eolian_mono/eolian/mono/function_definition.hh
index 9fef462002..67dfcc0ce4 100644
--- a/src/bin/eolian_mono/eolian/mono/function_definition.hh
+++ b/src/bin/eolian_mono/eolian/mono/function_definition.hh
@@ -32,41 +32,50 @@ struct native_function_definition_generator
32 bool generate(OutputIterator sink, attributes::function_def const& f, Context const& context) const 32 bool generate(OutputIterator sink, attributes::function_def const& f, Context const& context) const
33 { 33 {
34 EINA_CXX_DOM_LOG_DBG(eolian_mono::domain) << "native_function_definition_generator: " << f.c_name << std::endl; 34 EINA_CXX_DOM_LOG_DBG(eolian_mono::domain) << "native_function_definition_generator: " << f.c_name << std::endl;
35 if(blacklist::is_function_blacklisted(f, context) || f.is_static) // Only Concrete classes implement static methods. 35 if(blacklist::is_function_blacklisted(f, context))
36 return true; 36 return true;
37 else 37 else
38 { 38 {
39 if(!as_generator 39 if(!as_generator
40 ("\n\n" << scope_tab 40 ("\n\n" << scope_tab
41 << eolian_mono::marshall_native_annotation(true) 41 << eolian_mono::marshall_annotation(true)
42 << " private delegate " 42 << " private delegate "
43 << eolian_mono::marshall_type(true) 43 << eolian_mono::marshall_type(true)
44 << " " 44 << " "
45 << string 45 << string
46 << "_delegate(System.IntPtr obj, System.IntPtr pd" 46 << "_delegate(" << (f.is_static ? "" : "System.IntPtr obj, System.IntPtr pd")
47 << *grammar::attribute_reorder<-1, -1> 47 << ((!f.is_static && f.parameters.size() > 0) ? ", " : "")
48 << (grammar::attribute_reorder<-1, -1>
48 ( 49 (
49 (", " << marshall_native_annotation << " " << marshall_parameter) 50 (marshall_annotation << " " << marshall_parameter)
50 ) 51 ) % ", ")
51 << ");\n") 52 << ");\n")
52 .generate(sink, std::make_tuple(f.return_type, f.return_type, f.c_name, f.parameters), context)) 53 .generate(sink, std::make_tuple(f.return_type, f.return_type, f.c_name, f.parameters), context))
53 return false; 54 return false;
54 55
55 if(!as_generator 56 if(!as_generator
56 (scope_tab << "[System.Runtime.InteropServices.DllImport(" << context_find_tag<library_context>(context).actual_library_name(f.filename) << ")] " 57 ("\n\n" << scope_tab
57 << eolian_mono::marshall_native_annotation(true) 58 << eolian_mono::marshall_annotation(true)
58 << " private static extern " 59 << " public delegate "
59 << eolian_mono::marshall_type(true) 60 << eolian_mono::marshall_type(true)
60 << " " << string 61 << " "
61 << "(System.IntPtr obj" 62 << string << "_api_delegate(" << (f.is_static ? "" : "System.IntPtr obj")
62 << *grammar::attribute_reorder<-1, -1> 63 << ((!f.is_static && f.parameters.size() > 0) ? ", " : "")
64 << (grammar::attribute_reorder<-1, -1>
63 ( 65 (
64 (", " << marshall_native_annotation << " " << marshall_parameter) 66 (marshall_annotation << " " << marshall_parameter)
65 ) 67 ) % ", ")
66 << ");\n") 68 << ");\n")
67 .generate(sink, std::make_tuple(f.return_type, f.return_type, f.c_name, f.parameters), context)) 69 .generate(sink, std::make_tuple(f.return_type, f.return_type, f.c_name, f.parameters), context))
68 return false; 70 return false;
69 71
72 if(!as_generator
73 (scope_tab
74 << " public static Efl.Eo.FunctionWrapper<" << string << "_api_delegate> " << string << "_ptr = new Efl.Eo.FunctionWrapper<"
75 << string << "_api_delegate>(_Module, \"" << string << "\");\n")
76 .generate(sink, std::make_tuple(f.c_name, f.c_name, f.c_name, f.c_name), context))
77 return false;
78
70 std::string return_type; 79 std::string return_type;
71 if(!as_generator(eolian_mono::type(true)).generate(std::back_inserter(return_type), f.return_type, context)) 80 if(!as_generator(eolian_mono::type(true)).generate(std::back_inserter(return_type), f.return_type, context))
72 return false; 81 return false;
@@ -77,6 +86,11 @@ struct native_function_definition_generator
77 else 86 else
78 klass_cast_name = name_helpers::klass_interface_name(*klass); 87 klass_cast_name = name_helpers::klass_interface_name(*klass);
79 88
89 std::string self = "Efl.Eo.Globals.efl_super(obj, Efl.Eo.Globals.efl_class_get(obj))";
90
91 if (f.is_static)
92 self = "";
93
80 if(!as_generator 94 if(!as_generator
81 (scope_tab 95 (scope_tab
82 << " private static " 96 << " private static "
@@ -93,7 +107,8 @@ struct native_function_definition_generator
93 << scope_tab << scope_tab << "if(wrapper != null) {\n" 107 << scope_tab << scope_tab << "if(wrapper != null) {\n"
94 << scope_tab << scope_tab << scope_tab << eolian_mono::native_function_definition_preamble() 108 << scope_tab << scope_tab << scope_tab << eolian_mono::native_function_definition_preamble()
95 << scope_tab << scope_tab << scope_tab << "try {\n" 109 << scope_tab << scope_tab << scope_tab << "try {\n"
96 << scope_tab << scope_tab << scope_tab << scope_tab << (return_type != " void" ? "_ret_var = " : "") << "((" << klass_cast_name << ")wrapper)." << string 110 << scope_tab << scope_tab << scope_tab << scope_tab << (return_type != " void" ? "_ret_var = " : "")
111 << (f.is_static ? "" : "((") << klass_cast_name << (f.is_static ? "." : ")wrapper).") << string
97 << "(" << (native_argument_invocation % ", ") << ");\n" 112 << "(" << (native_argument_invocation % ", ") << ");\n"
98 << scope_tab << scope_tab << scope_tab << "} catch (Exception e) {\n" 113 << scope_tab << scope_tab << scope_tab << "} catch (Exception e) {\n"
99 << scope_tab << scope_tab << scope_tab << scope_tab << "Eina.Log.Warning($\"Callback error: {e.ToString()}\");\n" 114 << scope_tab << scope_tab << scope_tab << scope_tab << "Eina.Log.Warning($\"Callback error: {e.ToString()}\");\n"
@@ -102,7 +117,7 @@ struct native_function_definition_generator
102 << eolian_mono::native_function_definition_epilogue(*klass) 117 << eolian_mono::native_function_definition_epilogue(*klass)
103 << scope_tab << scope_tab << "} else {\n" 118 << scope_tab << scope_tab << "} else {\n"
104 << scope_tab << scope_tab << scope_tab << (return_type != " void" ? "return " : "") << string 119 << scope_tab << scope_tab << scope_tab << (return_type != " void" ? "return " : "") << string
105 << "(Efl.Eo.Globals.efl_super(obj, " << "Efl.Eo.Globals.efl_class_get(obj))" << *(", " << argument) << ");\n" 120 << "_ptr.Value.Delegate(" << self << ((!f.is_static && f.parameters.size() > 0) ? ", " : "") << (argument % ", ") << ");\n"
106 << scope_tab << scope_tab << "}\n" 121 << scope_tab << scope_tab << "}\n"
107 << scope_tab << "}\n" 122 << scope_tab << "}\n"
108 ) 123 )
@@ -118,9 +133,13 @@ struct native_function_definition_generator
118 , context)) 133 , context))
119 return false; 134 return false;
120 135
136 // Static functions do not need to be called from C
137 if (f.is_static)
138 return true;
139
121 // This is the delegate that will be passed to Eo to be called from C. 140 // This is the delegate that will be passed to Eo to be called from C.
122 if(!as_generator( 141 if(!as_generator(
123 scope_tab << "private " << f.c_name << "_delegate " << f.c_name << "_static_delegate;\n" 142 scope_tab << "private static " << f.c_name << "_delegate " << f.c_name << "_static_delegate;\n"
124 ).generate(sink, attributes::unused, context)) 143 ).generate(sink, attributes::unused, context))
125 return false; 144 return false;
126 return true; 145 return true;
@@ -141,22 +160,6 @@ struct function_definition_generator
141 if(blacklist::is_function_blacklisted(f, context)) 160 if(blacklist::is_function_blacklisted(f, context))
142 return true; 161 return true;
143 162
144 if(!as_generator
145 ("\n\n" << scope_tab << "[System.Runtime.InteropServices.DllImport(" << context_find_tag<library_context>(context).actual_library_name(f.filename) << ")]\n"
146 << scope_tab << eolian_mono::marshall_annotation(true)
147 << (do_super ? " protected " : " private ") << "static extern "
148 << eolian_mono::marshall_type(true)
149 << " " << string
150 << "(" << (f.is_static ? "" : "System.IntPtr obj")
151 << ((!f.is_static && (f.parameters.size() > 0)) ? ", " : "")
152 << (grammar::attribute_reorder<-1, -1>
153 (
154 (marshall_annotation << " " << marshall_parameter)
155 ) % ",")
156 << ");\n")
157 .generate(sink, std::make_tuple(f.return_type, f.return_type, f.c_name, f.parameters), context))
158 return false;
159
160 std::string return_type; 163 std::string return_type;
161 if(!as_generator(eolian_mono::type(true)).generate(std::back_inserter(return_type), f.return_type, context)) 164 if(!as_generator(eolian_mono::type(true)).generate(std::back_inserter(return_type), f.return_type, context))
162 return false; 165 return false;
@@ -176,8 +179,10 @@ struct function_definition_generator
176 if(!as_generator 179 if(!as_generator
177 (scope_tab << ((do_super && !f.is_static) ? "virtual " : "") << "public " << (f.is_static ? "static " : "") << return_type << " " << string << "(" << (parameter % ", ") 180 (scope_tab << ((do_super && !f.is_static) ? "virtual " : "") << "public " << (f.is_static ? "static " : "") << return_type << " " << string << "(" << (parameter % ", ")
178 << ") {\n " 181 << ") {\n "
179 << eolian_mono::function_definition_preamble() << string << "(" 182 << eolian_mono::function_definition_preamble()
180 << self << ((!f.is_static && (f.parameters.size() > 0)) ? "," : "") 183 << klass_full_native_inherit_name(f.klass) << "." << string << "_ptr.Value.Delegate("
184 << self
185 << ((!f.is_static && (f.parameters.size() > 0)) ? "," : "")
181 << (argument_invocation % ", ") << ");\n" 186 << (argument_invocation % ", ") << ");\n"
182 << eolian_mono::function_definition_epilogue() 187 << eolian_mono::function_definition_epilogue()
183 << " }\n") 188 << " }\n")
diff --git a/src/bin/eolian_mono/eolian/mono/function_pointer.hh b/src/bin/eolian_mono/eolian/mono/function_pointer.hh
index 2c62abeb12..a7e692bbad 100644
--- a/src/bin/eolian_mono/eolian/mono/function_pointer.hh
+++ b/src/bin/eolian_mono/eolian/mono/function_pointer.hh
@@ -47,9 +47,9 @@ struct function_pointer {
47 .generate(sink, std::make_tuple(f, f.return_type, f_name, f.parameters), funcptr_ctx)) 47 .generate(sink, std::make_tuple(f, f.return_type, f_name, f.parameters), funcptr_ctx))
48 return false; 48 return false;
49 // "Internal" delegate, 1-to-1 with the Unamaged function type 49 // "Internal" delegate, 1-to-1 with the Unamaged function type
50 if (!as_generator(marshall_native_annotation(true) 50 if (!as_generator(marshall_annotation(true)
51 << "public delegate " << marshall_type(true) << " " << string // public? 51 << "public delegate " << marshall_type(true) << " " << string // public?
52 << "Internal(IntPtr data" << *grammar::attribute_reorder<-1, -1>((", " << marshall_native_annotation << " " << marshall_parameter)) << ");\n") 52 << "Internal(IntPtr data" << *grammar::attribute_reorder<-1, -1>((", " << marshall_annotation << " " << marshall_parameter)) << ");\n")
53 .generate(sink, std::make_tuple(f.return_type, f.return_type, f_name, f.parameters), funcptr_ctx)) 53 .generate(sink, std::make_tuple(f.return_type, f.return_type, f_name, f.parameters), funcptr_ctx))
54 return false; 54 return false;
55 55
@@ -80,8 +80,8 @@ struct function_pointer {
80 << scope_tab << "}\n\n" 80 << scope_tab << "}\n\n"
81 81
82 82
83 << scope_tab << marshall_native_annotation(true) 83 << scope_tab << marshall_annotation(true)
84 << scope_tab << "internal static " << marshall_type(true) << " Cb(IntPtr cb_data" << *grammar::attribute_reorder<-1, -1>((", " << marshall_native_annotation << " " << marshall_parameter)) << ")\n" 84 << scope_tab << "internal static " << marshall_type(true) << " Cb(IntPtr cb_data" << *grammar::attribute_reorder<-1, -1>((", " << marshall_annotation << " " << marshall_parameter)) << ")\n"
85 << scope_tab << "{\n" 85 << scope_tab << "{\n"
86 << scope_tab << scope_tab << "GCHandle handle = GCHandle.FromIntPtr(cb_data);\n" 86 << scope_tab << scope_tab << "GCHandle handle = GCHandle.FromIntPtr(cb_data);\n"
87 << scope_tab << scope_tab << string << " cb = (" << string << ")handle.Target;\n" 87 << scope_tab << scope_tab << string << " cb = (" << string << ")handle.Target;\n"
diff --git a/src/bin/eolian_mono/eolian/mono/function_registration.hh b/src/bin/eolian_mono/eolian/mono/function_registration.hh
index 90cbbc485d..cc7534b29a 100644
--- a/src/bin/eolian_mono/eolian/mono/function_registration.hh
+++ b/src/bin/eolian_mono/eolian/mono/function_registration.hh
@@ -37,7 +37,8 @@ struct function_registration_generator
37 // auto index = index_generator(); 37 // auto index = index_generator();
38 38
39 if(!as_generator( 39 if(!as_generator(
40 scope_tab << scope_tab << f.c_name << "_static_delegate = new " << f.c_name << "_delegate(" << 40 scope_tab << scope_tab << "if (" << f.c_name << "_static_delegate == null)\n"
41 << scope_tab << scope_tab << f.c_name << "_static_delegate = new " << f.c_name << "_delegate(" <<
41 escape_keyword(f.name) << ");\n" 42 escape_keyword(f.name) << ");\n"
42 ).generate(sink, attributes::unused, context)) 43 ).generate(sink, attributes::unused, context))
43 return false; 44 return false;
@@ -47,9 +48,9 @@ struct function_registration_generator
47#ifdef _WIN32 48#ifdef _WIN32
48 << "api_func = Marshal.StringToHGlobalAnsi(\"" << string << "\")" 49 << "api_func = Marshal.StringToHGlobalAnsi(\"" << string << "\")"
49#else 50#else
50 << "api_func = Efl.Eo.Globals.dlsym(Efl.Eo.Globals.RTLD_DEFAULT, \"" << string << "\")" 51 << "api_func = Efl.Eo.FunctionInterop.LoadFunctionPointer(_Module.Module, \"" << string << "\")"
51#endif 52#endif
52 ", func = Marshal.GetFunctionPointerForDelegate(" << string << "_static_delegate)});\n" 53 << ", func = Marshal.GetFunctionPointerForDelegate(" << string << "_static_delegate)});\n"
53 ) 54 )
54 .generate(sink, std::make_tuple(f.c_name, f.c_name), context)) 55 .generate(sink, std::make_tuple(f.c_name, f.c_name), context))
55 return false; 56 return false;
diff --git a/src/bin/eolian_mono/eolian/mono/klass.hh b/src/bin/eolian_mono/eolian/mono/klass.hh
index e70729b6ae..993378fa21 100644
--- a/src/bin/eolian_mono/eolian/mono/klass.hh
+++ b/src/bin/eolian_mono/eolian/mono/klass.hh
@@ -374,9 +374,10 @@ struct klass
374 374
375 if(!as_generator 375 if(!as_generator
376 ( 376 (
377 "public class " << native_inherit_name << " " << (root ? ": Efl.Eo.NativeClass" : (": " + base_name)) <<"{\n" 377 "public class " << native_inherit_name << " " << (root ? " : Efl.Eo.NativeClass" : (": " + base_name)) <<"{\n"
378 // << scope_tab << (root ? "protected IntPtr EoKlass { get; set; }\n" : "\n") 378 << scope_tab << "public " << (root ? "" : "new ") << " static Efl.Eo.NativeModule _Module = new Efl.Eo.NativeModule("
379 << scope_tab << "public " << /*(root ? "" : "new ")*/ "override " << "System.Collections.Generic.List<Efl_Op_Description> GetEoOps(System.Type type)\n" 379 << context_find_tag<library_context>(context).actual_library_name(cls.filename) << ");\n"
380 << scope_tab << "public override System.Collections.Generic.List<Efl_Op_Description> GetEoOps(System.Type type)\n"
380 << scope_tab << "{\n" 381 << scope_tab << "{\n"
381 << scope_tab << scope_tab << "var descs = new System.Collections.Generic.List<Efl_Op_Description>();\n" 382 << scope_tab << scope_tab << "var descs = new System.Collections.Generic.List<Efl_Op_Description>();\n"
382 ) 383 )
@@ -488,8 +489,6 @@ struct klass
488 489
489 return as_generator( 490 return as_generator(
490 scope_tab << visibility << " System.IntPtr handle;\n" 491 scope_tab << visibility << " System.IntPtr handle;\n"
491 << scope_tab << "public Dictionary<String, IntPtr> cached_strings = new Dictionary<String, IntPtr>();" << "\n"
492 << scope_tab << "public Dictionary<String, IntPtr> cached_stringshares = new Dictionary<String, IntPtr>();" << "\n"
493 << scope_tab << "///<summary>Pointer to the native instance.</summary>\n" 492 << scope_tab << "///<summary>Pointer to the native instance.</summary>\n"
494 << scope_tab << "public System.IntPtr NativeHandle {\n" 493 << scope_tab << "public System.IntPtr NativeHandle {\n"
495 << scope_tab << scope_tab << "get { return handle; }\n" 494 << scope_tab << scope_tab << "get { return handle; }\n"
@@ -603,8 +602,6 @@ struct klass
603 << scope_tab << "///<summary>Releases the underlying native instance.</summary>\n" 602 << scope_tab << "///<summary>Releases the underlying native instance.</summary>\n"
604 << scope_tab << "public void Dispose()\n" 603 << scope_tab << "public void Dispose()\n"
605 << scope_tab << "{\n" 604 << scope_tab << "{\n"
606 << scope_tab << "Efl.Eo.Globals.free_dict_values(cached_strings);" << "\n"
607 << scope_tab << "Efl.Eo.Globals.free_stringshare_values(cached_stringshares);" << "\n"
608 << scope_tab << scope_tab << "Dispose(true);\n" 605 << scope_tab << scope_tab << "Dispose(true);\n"
609 << scope_tab << scope_tab << "GC.SuppressFinalize(this);\n" 606 << scope_tab << scope_tab << "GC.SuppressFinalize(this);\n"
610 << scope_tab << "}\n" 607 << scope_tab << "}\n"
@@ -681,13 +678,13 @@ struct klass
681 678
682 // Callback registration functions 679 // Callback registration functions
683 if (!as_generator( 680 if (!as_generator(
684 scope_tab << visibility << "bool add_cpp_event_handler(string key, Efl.EventCb evt_delegate) {\n" 681 scope_tab << visibility << "bool add_cpp_event_handler(string lib, string key, Efl.EventCb evt_delegate) {\n"
685 << scope_tab << scope_tab << "int event_count = 0;\n" 682 << scope_tab << scope_tab << "int event_count = 0;\n"
686 << scope_tab << scope_tab << "if (!event_cb_count.TryGetValue(key, out event_count))\n" 683 << scope_tab << scope_tab << "if (!event_cb_count.TryGetValue(key, out event_count))\n"
687 << scope_tab << scope_tab << scope_tab << "event_cb_count[key] = event_count;\n" 684 << scope_tab << scope_tab << scope_tab << "event_cb_count[key] = event_count;\n"
688 << scope_tab << scope_tab << "if (event_count == 0) {\n" 685 << scope_tab << scope_tab << "if (event_count == 0) {\n"
689 686
690 << scope_tab << scope_tab << scope_tab << "IntPtr desc = Efl.EventDescription.GetNative(key);\n" 687 << scope_tab << scope_tab << scope_tab << "IntPtr desc = Efl.EventDescription.GetNative(lib, key);\n"
691 << scope_tab << scope_tab << scope_tab << "if (desc == IntPtr.Zero) {\n" 688 << scope_tab << scope_tab << scope_tab << "if (desc == IntPtr.Zero) {\n"
692 << scope_tab << scope_tab << scope_tab << scope_tab << "Eina.Log.Error($\"Failed to get native event {key}\");\n" 689 << scope_tab << scope_tab << scope_tab << scope_tab << "Eina.Log.Error($\"Failed to get native event {key}\");\n"
693 << scope_tab << scope_tab << scope_tab << scope_tab << "return false;\n" 690 << scope_tab << scope_tab << scope_tab << scope_tab << "return false;\n"
@@ -709,7 +706,8 @@ struct klass
709 << scope_tab << scope_tab << scope_tab << "event_cb_count[key] = event_count;\n" 706 << scope_tab << scope_tab << scope_tab << "event_cb_count[key] = event_count;\n"
710 << scope_tab << scope_tab << "if (event_count == 1) {\n" 707 << scope_tab << scope_tab << "if (event_count == 1) {\n"
711 708
712 << scope_tab << scope_tab << scope_tab << "IntPtr desc = Efl.EventDescription.GetNative(key);\n" 709 << scope_tab << scope_tab << scope_tab << "IntPtr desc = Efl.EventDescription.GetNative("
710 << context_find_tag<library_context>(context).actual_library_name(cls.filename) << ", key);\n"
713 << scope_tab << scope_tab << scope_tab << "if (desc == IntPtr.Zero) {\n" 711 << scope_tab << scope_tab << scope_tab << "if (desc == IntPtr.Zero) {\n"
714 << scope_tab << scope_tab << scope_tab << scope_tab << "Eina.Log.Error($\"Failed to get native event {key}\");\n" 712 << scope_tab << scope_tab << scope_tab << scope_tab << "Eina.Log.Error($\"Failed to get native event {key}\");\n"
715 << scope_tab << scope_tab << scope_tab << scope_tab << "return false;\n" 713 << scope_tab << scope_tab << scope_tab << scope_tab << "return false;\n"
diff --git a/src/bin/eolian_mono/eolian/mono/marshall_annotation.hh b/src/bin/eolian_mono/eolian/mono/marshall_annotation.hh
index 744b4f8720..4159b6a952 100644
--- a/src/bin/eolian_mono/eolian/mono/marshall_annotation.hh
+++ b/src/bin/eolian_mono/eolian/mono/marshall_annotation.hh
@@ -90,7 +90,7 @@ struct marshall_annotation_visitor_generate
90 {"string", true, [&] { 90 {"string", true, [&] {
91 return " [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringPassOwnershipMarshaler))]"; 91 return " [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringPassOwnershipMarshaler))]";
92 }}, 92 }},
93 {"string", false, [&] { 93 {"string", nullptr, [&] {
94 return " [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringKeepOwnershipMarshaler))]"; 94 return " [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringKeepOwnershipMarshaler))]";
95 }}, 95 }},
96 {"mstring", true, [&] { 96 {"mstring", true, [&] {
@@ -112,10 +112,10 @@ struct marshall_annotation_visitor_generate
112 return " [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Eina.ValueMarshaler))]"; 112 return " [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Eina.ValueMarshaler))]";
113 }}, 113 }},
114 {"strbuf", true, [&] { 114 {"strbuf", true, [&] {
115 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StrbufPassOwnershipMarshaler))]"; 115 return " [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StrbufPassOwnershipMarshaler))]";
116 }}, 116 }},
117 {"strbuf", false, [&] { 117 {"strbuf", false, [&] {
118 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StrbufKeepOwnershipMarshaler))]"; 118 return " [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StrbufKeepOwnershipMarshaler))]";
119 }}, 119 }},
120 }; 120 };
121 121
@@ -169,128 +169,6 @@ struct marshall_annotation_visitor_generate
169 return true; 169 return true;
170 } 170 }
171}; 171};
172
173template <typename OutputIterator, typename Context>
174struct marshall_native_annotation_visitor_generate
175{
176 mutable OutputIterator sink;
177 Context const* context;
178 std::string c_type;
179 bool is_out;
180 bool is_return;
181 bool is_ptr;
182
183 typedef marshall_type_visitor_generate<OutputIterator, Context> visitor_type;
184 typedef bool result_type;
185
186 bool operator()(attributes::regular_type_def const& regular) const
187 {
188 using attributes::regular_type_def;
189 struct match
190 {
191 eina::optional<std::string> name;
192 eina::optional<bool> has_own;
193 std::function<std::string()> function;
194 };
195 match const parameter_match_table[] =
196 {
197 // signed primitives
198 {"bool", nullptr, [&] { return " [MarshalAs(UnmanagedType.U1)]"; }},
199 {"string", true, [&] {
200 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringPassOwnershipMarshaler))]";
201 }},
202 {"string", false, [&] {
203 if (is_out)
204 return "";
205 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringKeepOwnershipMarshaler))]";
206 }},
207 {"stringshare", true, [&] {
208 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringsharePassOwnershipMarshaler))]";
209 }},
210 {"stringshare", false, [&] {
211 if (is_out)
212 return "";
213 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringshareKeepOwnershipMarshaler))]";
214 }},
215 {"strbuf", true, [&] {
216 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StrbufPassOwnershipMarshaler))]";
217 }},
218 {"strbuf", false, [&] {
219 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StrbufKeepOwnershipMarshaler))]";
220 }},
221 };
222 match const return_match_table[] =
223 {
224 // signed primitives
225 {"bool", nullptr, [&] { return " [return: MarshalAs(UnmanagedType.U1)]"; }},
226 {"string", true, [&] {
227 return " [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringPassOwnershipMarshaler))]";
228 }},
229 {"string", false, [&] { return ""; }},
230 {"stringshare", true, [&] {
231 return " [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringsharePassOwnershipMarshaler))]";
232 }},
233 {"stringshare", false, [&] { return ""; }},
234 {"strbuf", true, [&] {
235 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StrbufPassOwnershipMarshaler))]";
236 }},
237 {"strbuf", false, [&] {
238 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StrbufKeepOwnershipMarshaler))]";
239 }},
240 };
241
242 if(eina::optional<bool> b = call_annotation_match
243 ((is_return ? return_match_table : parameter_match_table)
244 , [&] (match const& m)
245 {
246 return (!m.name || *m.name == regular.base_type)
247 && (!m.has_own || *m.has_own == (bool)(regular.base_qualifier & qualifier_info::is_own))
248 ;
249 }
250 , [&] (std::string const& string)
251 {
252 std::copy(string.begin(), string.end(), sink);
253 return true;
254 }))
255 {
256 return *b;
257 }
258 else
259 {
260 return true;
261 }
262 }
263 bool operator()(attributes::klass_name const& klass_name) const
264 {
265 const char *return_prefix = is_return ? "return:" : "";
266 const char *marshal_prefix = "MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(";
267
268 std::string name = name_helpers::klass_full_concrete_name(klass_name);
269
270 if (name == "Efl.Class")
271 name = "Efl.Eo.MarshalEflClass";
272 else
273 {
274 auto own = klass_name.base_qualifier & qualifier_info::is_own ? "OwnTag" : "NonOwnTag";
275 name = "Efl.Eo.MarshalTest<" + name + ", Efl.Eo." + own + ">";
276 }
277
278 return as_generator(
279 lit("[") << return_prefix << marshal_prefix << name << "))]"
280 ).generate(sink, name, *context);
281 }
282 bool operator()(attributes::complex_type_def const& c) const
283 {
284 if (c.outer.base_type == "future")
285 {
286 std::string prefix = is_return ? "return: " : "";
287 return as_generator("[" << prefix << "MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Eina.FutureMarshaler))]").generate(sink, nullptr, *context);
288 }
289 return true;
290 }
291};
292
293
294} } 172} }
295 173
296#endif 174#endif
diff --git a/src/bin/eolian_mono/eolian/mono/marshall_type.hh b/src/bin/eolian_mono/eolian/mono/marshall_type.hh
index add954ade2..5c350adebe 100644
--- a/src/bin/eolian_mono/eolian/mono/marshall_type.hh
+++ b/src/bin/eolian_mono/eolian/mono/marshall_type.hh
@@ -13,8 +13,6 @@ template <typename OutputIterator, typename Context>
13struct marshall_type_visitor_generate; 13struct marshall_type_visitor_generate;
14template <typename OutputIterator, typename Context> 14template <typename OutputIterator, typename Context>
15struct marshall_annotation_visitor_generate; 15struct marshall_annotation_visitor_generate;
16template <typename OutputIterator, typename Context>
17struct marshall_native_annotation_visitor_generate;
18} 16}
19 17
20/* 18/*
@@ -73,26 +71,6 @@ struct marshall_annotation_generator
73 bool is_return; 71 bool is_return;
74}; 72};
75 73
76struct marshall_native_annotation_generator
77{
78 marshall_native_annotation_generator(bool is_return = false)
79 : is_return(is_return) {}
80
81 template <typename OutputIterator, typename Context>
82 bool generate(OutputIterator sink, attributes::type_def const& type, Context const& context) const
83 {
84 return type.original_type.visit(detail::marshall_native_annotation_visitor_generate<OutputIterator, Context>{sink, &context, type.c_type, false, is_return, type.is_ptr});
85 }
86 template <typename OutputIterator, typename Context>
87 bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
88 {
89 return param.type.original_type.visit(detail::marshall_native_annotation_visitor_generate<OutputIterator, Context>{sink, &context, param.type.c_type
90 , param.direction != attributes::parameter_direction::in, false, param.type.is_ptr});
91 }
92
93 bool is_return;
94};
95
96struct marshall_type_terminal 74struct marshall_type_terminal
97{ 75{
98 marshall_type_generator const operator()(bool is_return) const 76 marshall_type_generator const operator()(bool is_return) const
@@ -120,19 +98,6 @@ marshall_annotation_generator const as_generator(marshall_annotation_terminal)
120} 98}
121 99
122 100
123struct marshall_native_annotation_terminal
124{
125 marshall_native_annotation_generator const operator()(bool is_return) const
126 {
127 return marshall_native_annotation_generator(is_return);
128 }
129} const marshall_native_annotation = {};
130
131marshall_native_annotation_generator const as_generator(marshall_native_annotation_terminal)
132{
133 return marshall_native_annotation_generator{};
134}
135
136} 101}
137 102
138namespace efl { namespace eolian { namespace grammar { 103namespace efl { namespace eolian { namespace grammar {
@@ -158,23 +123,12 @@ struct is_generator< ::eolian_mono::marshall_annotation_generator> : std::true_t
158template <> 123template <>
159struct is_generator< ::eolian_mono::marshall_annotation_terminal> : std::true_type {}; 124struct is_generator< ::eolian_mono::marshall_annotation_terminal> : std::true_type {};
160 125
161template <>
162struct is_eager_generator< ::eolian_mono::marshall_native_annotation_generator> : std::true_type {};
163template <>
164struct is_generator< ::eolian_mono::marshall_native_annotation_generator> : std::true_type {};
165template <>
166struct is_generator< ::eolian_mono::marshall_native_annotation_terminal> : std::true_type {};
167
168namespace type_traits { 126namespace type_traits {
169template <> 127template <>
170struct attributes_needed< ::eolian_mono::marshall_annotation_generator> : std::integral_constant<int, 1> {}; 128struct attributes_needed< ::eolian_mono::marshall_annotation_generator> : std::integral_constant<int, 1> {};
171template <> 129template <>
172struct attributes_needed< ::eolian_mono::marshall_annotation_terminal> : std::integral_constant<int, 1> {}; 130struct attributes_needed< ::eolian_mono::marshall_annotation_terminal> : std::integral_constant<int, 1> {};
173 131
174template <>
175struct attributes_needed< ::eolian_mono::marshall_native_annotation_generator> : std::integral_constant<int, 1> {};
176template <>
177struct attributes_needed< ::eolian_mono::marshall_native_annotation_terminal> : std::integral_constant<int, 1> {};
178} 132}
179 133
180} } } 134} } }
diff --git a/src/bin/eolian_mono/eolian/mono/marshall_type_impl.hh b/src/bin/eolian_mono/eolian/mono/marshall_type_impl.hh
index 3bd8791e89..998ca0bdb3 100644
--- a/src/bin/eolian_mono/eolian/mono/marshall_type_impl.hh
+++ b/src/bin/eolian_mono/eolian/mono/marshall_type_impl.hh
@@ -32,7 +32,6 @@ struct marshall_type_visitor_generate
32 bool operator()(attributes::regular_type_def const& regular) const 32 bool operator()(attributes::regular_type_def const& regular) const
33 { 33 {
34 using attributes::regular_type_def; 34 using attributes::regular_type_def;
35 bool is_inherit_native = context_find_tag<class_context>(*context).current_wrapper_kind == class_context::inherit_native;
36 35
37 struct match 36 struct match
38 { 37 {
@@ -47,32 +46,24 @@ struct marshall_type_visitor_generate
47 { 46 {
48 regular_type_def r = regular; 47 regular_type_def r = regular;
49 r.base_qualifier.qualifier ^= qualifier_info::is_ref; 48 r.base_qualifier.qualifier ^= qualifier_info::is_ref;
50 // if(is_out || is_return)
51 return replace_base_type(r, " System.String"); 49 return replace_base_type(r, " System.String");
52 // else return replace_base_type(r, " ::efl::eina::string_view");
53 }} 50 }}
54 , {"string", false, [&] 51 , {"string", false, [&]
55 { 52 {
56 regular_type_def r = regular; 53 regular_type_def r = regular;
57 r.base_qualifier.qualifier ^= qualifier_info::is_ref; 54 r.base_qualifier.qualifier ^= qualifier_info::is_ref;
58 if (is_inherit_native && (is_return || is_out))
59 return replace_base_type(r, " System.IntPtr");
60 return replace_base_type(r, " System.String"); 55 return replace_base_type(r, " System.String");
61 }} 56 }}
62 , {"mstring", true, [&] 57 , {"mstring", true, [&]
63 { 58 {
64 regular_type_def r = regular; 59 regular_type_def r = regular;
65 r.base_qualifier.qualifier ^= qualifier_info::is_ref; 60 r.base_qualifier.qualifier ^= qualifier_info::is_ref;
66 // if(is_out || is_return)
67 return replace_base_type(r, " System.String"); 61 return replace_base_type(r, " System.String");
68 // else return replace_base_type(r, " ::efl::eina::string_view");
69 }} 62 }}
70 , {"mstring", false, [&] 63 , {"mstring", false, [&]
71 { 64 {
72 regular_type_def r = regular; 65 regular_type_def r = regular;
73 r.base_qualifier.qualifier ^= qualifier_info::is_ref; 66 r.base_qualifier.qualifier ^= qualifier_info::is_ref;
74 if (is_inherit_native && (is_return || is_out))
75 return replace_base_type(r, " System.IntPtr");
76 return replace_base_type(r, " System.String"); 67 return replace_base_type(r, " System.String");
77 }} 68 }}
78 , {"stringshare", true, [&] 69 , {"stringshare", true, [&]
@@ -85,10 +76,7 @@ struct marshall_type_visitor_generate
85 { 76 {
86 regular_type_def r = regular; 77 regular_type_def r = regular;
87 r.base_qualifier.qualifier ^= qualifier_info::is_ref; 78 r.base_qualifier.qualifier ^= qualifier_info::is_ref;
88 if (is_inherit_native && (is_return || is_out)) 79 return replace_base_type(r, " System.String");
89 return replace_base_type(r, " System.IntPtr");
90 else
91 return replace_base_type(r, " System.String");
92 }} 80 }}
93 , {"strbuf", nullptr, [&] 81 , {"strbuf", nullptr, [&]
94 { 82 {
@@ -193,7 +181,6 @@ struct marshall_type_visitor_generate
193 bool operator()(attributes::klass_name klass_name) const 181 bool operator()(attributes::klass_name klass_name) const
194 { 182 {
195 return visitor_generate<OutputIterator, Context>{sink, context, c_type, is_out, is_return, is_ptr}(klass_name); 183 return visitor_generate<OutputIterator, Context>{sink, context, c_type, is_out, is_return, is_ptr}(klass_name);
196 // return as_generator(" System.IntPtr").generate(sink, attributes::unused, *context);
197 } 184 }
198 bool operator()(attributes::complex_type_def const& complex) const 185 bool operator()(attributes::complex_type_def const& complex) const
199 { 186 {
@@ -237,14 +224,8 @@ struct marshall_type_visitor_generate
237 auto default_match = [&] (attributes::complex_type_def const& complex) 224 auto default_match = [&] (attributes::complex_type_def const& complex)
238 { 225 {
239 regular_type_def no_pointer_regular = complex.outer; 226 regular_type_def no_pointer_regular = complex.outer;
240 // std::vector<attributes::pointer_indirection> pointers;
241 // pointers.swap(no_pointer_regular.pointers);
242 // if(is_out)
243 // pointers.push_back({{attributes::qualifier_info::is_none, {}}, true});
244 return visitor_type{sink, context, c_type, false}(no_pointer_regular) 227 return visitor_type{sink, context, c_type, false}(no_pointer_regular)
245 && as_generator("<" << (type % ", ") << ">").generate(sink, complex.subtypes, *context) 228 && as_generator("<" << (type % ", ") << ">").generate(sink, complex.subtypes, *context);
246 ;
247 // && detail::generate_pointers(sink, pointers, *context, false);
248 }; 229 };
249 230
250 if(eina::optional<bool> b = call_match 231 if(eina::optional<bool> b = call_match
@@ -269,12 +250,9 @@ struct marshall_type_visitor_generate
269 return *b; 250 return *b;
270 } 251 }
271 252
272 //return default_match(complex);
273 return visitor_generate<OutputIterator, Context>{sink, context, c_type, is_out, is_return, is_ptr}(complex); 253 return visitor_generate<OutputIterator, Context>{sink, context, c_type, is_out, is_return, is_ptr}(complex);
274 // return as_generator(" System.IntPtr").generate(sink, attributes::unused, *context);
275 } 254 }
276}; 255};
277
278} } 256} }
279 257
280#endif 258#endif
diff --git a/src/bin/eolian_mono/eolian/mono/name_helpers.hh b/src/bin/eolian_mono/eolian/mono/name_helpers.hh
index ccbbfce3b4..5fc1f18d22 100644
--- a/src/bin/eolian_mono/eolian/mono/name_helpers.hh
+++ b/src/bin/eolian_mono/eolian/mono/name_helpers.hh
@@ -364,13 +364,27 @@ inline std::string klass_inherit_name(T const& klass)
364template<typename T> 364template<typename T>
365inline std::string klass_native_inherit_name(T const& klass) 365inline std::string klass_native_inherit_name(T const& klass)
366{ 366{
367 return klass_concrete_name(klass) + "NativeInherit"; 367 switch(klass.type)
368 {
369 case attributes::class_type::abstract_:
370 case attributes::class_type::regular:
371 return klass_concrete_name(klass) + "NativeInherit";
372 default:
373 return klass_interface_name(klass) + "NativeInherit";
374 }
368} 375}
369 376
370template<typename T> 377template<typename T>
371inline std::string klass_full_native_inherit_name(T const& klass) 378inline std::string klass_full_native_inherit_name(T const& klass)
372{ 379{
373 return klass_full_concrete_name(klass) + "NativeInherit"; 380 switch(klass.type)
381 {
382 case attributes::class_type::abstract_:
383 case attributes::class_type::regular:
384 return klass_full_concrete_name(klass) + "NativeInherit";
385 default:
386 return klass_full_interface_name(klass) + "NativeInherit";
387 }
374} 388}
375 389
376template<typename T> 390template<typename T>
diff --git a/src/bin/eolian_mono/eolian/mono/parameter.hh b/src/bin/eolian_mono/eolian/mono/parameter.hh
index ab4362519b..1314c125cb 100644
--- a/src/bin/eolian_mono/eolian/mono/parameter.hh
+++ b/src/bin/eolian_mono/eolian/mono/parameter.hh
@@ -1112,7 +1112,7 @@ struct native_convert_out_assign_generator
1112 return false; 1112 return false;
1113 } 1113 }
1114 return as_generator( 1114 return as_generator(
1115 string << "= Efl.Eo.Globals.cached_stringshare_to_intptr(((" << name_helpers::klass_inherit_name(*klass) << ")wrapper).cached_stringshares, " << string << ");\n" 1115 string << "= " << string << ";\n"
1116 ).generate(sink, std::make_tuple(escape_keyword(param.param_name), out_variable_name(param.param_name)), context); 1116 ).generate(sink, std::make_tuple(escape_keyword(param.param_name), out_variable_name(param.param_name)), context);
1117 } 1117 }
1118 else if (param_is_acceptable(param, "const char *", !WANT_OWN, WANT_OUT)) 1118 else if (param_is_acceptable(param, "const char *", !WANT_OWN, WANT_OUT))
@@ -1123,7 +1123,7 @@ struct native_convert_out_assign_generator
1123 return false; 1123 return false;
1124 } 1124 }
1125 return as_generator( 1125 return as_generator(
1126 string << "= Efl.Eo.Globals.cached_string_to_intptr(((" << name_helpers::klass_inherit_name(*klass) << ")wrapper).cached_strings, " << string << ");\n" 1126 string << " = " << string << ";\n"
1127 ).generate(sink, std::make_tuple(escape_keyword(param.param_name), out_variable_name(param.param_name)), context); 1127 ).generate(sink, std::make_tuple(escape_keyword(param.param_name), out_variable_name(param.param_name)), context);
1128 } 1128 }
1129 else if (param_is_acceptable(param, "Eina_Binbuf *", WANT_OWN, WANT_OUT) 1129 else if (param_is_acceptable(param, "Eina_Binbuf *", WANT_OWN, WANT_OUT)
@@ -1253,7 +1253,7 @@ struct native_convert_return_generator
1253 return false; 1253 return false;
1254 } 1254 }
1255 return as_generator( 1255 return as_generator(
1256 "return Efl.Eo.Globals.cached_string_to_intptr(((" << name_helpers::klass_inherit_name(*klass) << ")wrapper).cached_strings, _ret_var);\n" 1256 "return _ret_var;\n"
1257 ).generate(sink, attributes::unused, context); 1257 ).generate(sink, attributes::unused, context);
1258 } 1258 }
1259 else 1259 else
@@ -1271,7 +1271,7 @@ struct native_convert_return_generator
1271 return false; 1271 return false;
1272 } 1272 }
1273 return as_generator( 1273 return as_generator(
1274 "return Efl.Eo.Globals.cached_stringshare_to_intptr(((" << name_helpers::klass_inherit_name(*klass) << ")wrapper).cached_stringshares, _ret_var);\n" 1274 "return _ret_var;\n"
1275 ).generate(sink, attributes::unused, context); 1275 ).generate(sink, attributes::unused, context);
1276 } 1276 }
1277 else 1277 else
diff --git a/src/bin/eolian_mono/eolian/mono/part_definition.hh b/src/bin/eolian_mono/eolian/mono/part_definition.hh
index bd12ee2a40..47951f4bf1 100644
--- a/src/bin/eolian_mono/eolian/mono/part_definition.hh
+++ b/src/bin/eolian_mono/eolian/mono/part_definition.hh
@@ -24,7 +24,7 @@ struct part_definition_generator
24 << scope_tab << "{\n" 24 << scope_tab << "{\n"
25 << scope_tab << scope_tab << "get\n" 25 << scope_tab << scope_tab << "get\n"
26 << scope_tab << scope_tab << "{\n" 26 << scope_tab << scope_tab << "{\n"
27 << scope_tab << scope_tab << scope_tab << "Efl.Object obj = efl_part_get(NativeHandle, \"" << part.name << "\");\n" 27 << scope_tab << scope_tab << scope_tab << "Efl.Object obj = Efl.PartNativeInherit.efl_part_get_ptr.Value.Delegate(NativeHandle, \"" << part.name << "\");\n"
28 << scope_tab << scope_tab << scope_tab << "return " << part_klass_name << ".static_cast(obj);\n" 28 << scope_tab << scope_tab << scope_tab << "return " << part_klass_name << ".static_cast(obj);\n"
29 << scope_tab << scope_tab << "}\n" 29 << scope_tab << scope_tab << "}\n"
30 << scope_tab << "}\n" 30 << scope_tab << "}\n"
diff --git a/src/bin/eolian_mono/eolian/mono/struct_definition.hh b/src/bin/eolian_mono/eolian/mono/struct_definition.hh
index 7802b4518c..17485d12e4 100644
--- a/src/bin/eolian_mono/eolian/mono/struct_definition.hh
+++ b/src/bin/eolian_mono/eolian/mono/struct_definition.hh
@@ -131,6 +131,22 @@ struct struct_internal_definition_generator
131 .generate(sink, nullptr, context)) 131 .generate(sink, nullptr, context))
132 return false; 132 return false;
133 } 133 }
134 else if (regular && !(regular->base_qualifier & efl::eolian::grammar::attributes::qualifier_info::is_ref)
135 && regular->base_type == "bool")
136 {
137 if (!as_generator("///<summary>Internal wrapper for field " << field_name << "</summary>\n"
138 "public System.Byte " << field_name << ";\n")
139 .generate(sink, nullptr, context))
140 return false;
141 }
142 else if (regular && !(regular->base_qualifier & efl::eolian::grammar::attributes::qualifier_info::is_ref)
143 && regular->base_type == "char")
144 {
145 if (!as_generator("///<summary>Internal wrapper for field " << field_name << "</summary>\n"
146 "public System.Byte " << field_name << ";\n")
147 .generate(sink, nullptr, context))
148 return false;
149 }
134 else if (!as_generator(scope_tab << eolian_mono::marshall_annotation(false) << "\n" 150 else if (!as_generator(scope_tab << eolian_mono::marshall_annotation(false) << "\n"
135 << scope_tab << "public " << eolian_mono::marshall_type(false) << " " << string << ";\n") 151 << scope_tab << "public " << eolian_mono::marshall_type(false) << " " << string << ";\n")
136 .generate(sink, std::make_tuple(field.type, field.type, field_name), context)) 152 .generate(sink, std::make_tuple(field.type, field.type, field_name), context))
@@ -255,6 +271,20 @@ struct to_internal_field_convert_generator
255 ).generate(sink, std::make_tuple(field_name, field_name), context)) 271 ).generate(sink, std::make_tuple(field_name, field_name), context))
256 return false; 272 return false;
257 } 273 }
274 else if (!field.type.is_ptr && regular && regular->base_type == "bool")
275 {
276 if (!as_generator(
277 scope_tab << scope_tab << "_internal_struct." << string << " = _external_struct." << string << " ? (byte)1 : (byte)0;\n")
278 .generate(sink, std::make_tuple(field_name, field_name), context))
279 return false;
280 }
281 else if (!field.type.is_ptr && regular && regular->base_type == "char")
282 {
283 if (!as_generator(
284 scope_tab << scope_tab << "_internal_struct." << string << " = (byte)_external_struct." << string << ";\n")
285 .generate(sink, std::make_tuple(field_name, field_name), context))
286 return false;
287 }
258 else // primitives and enums 288 else // primitives and enums
259 { 289 {
260 if (!as_generator( 290 if (!as_generator(
@@ -358,6 +388,20 @@ struct to_external_field_convert_generator
358 ).generate(sink, std::make_tuple(field_name, field_name), context)) 388 ).generate(sink, std::make_tuple(field_name, field_name), context))
359 return false; 389 return false;
360 } 390 }
391 else if (!field.type.is_ptr && regular && regular->base_type == "bool")
392 {
393 if (!as_generator(
394 scope_tab << scope_tab << "_external_struct." << string << " = _internal_struct." << string << " != 0;\n"
395 ).generate(sink, std::make_tuple(field_name, field_name), context))
396 return false;
397 }
398 else if (!field.type.is_ptr && regular && regular->base_type == "char")
399 {
400 if (!as_generator(
401 scope_tab << scope_tab << "_external_struct." << string << " = (char)_internal_struct." << string << ";\n"
402 ).generate(sink, std::make_tuple(field_name, field_name), context))
403 return false;
404 }
361 else // primitives and enums 405 else // primitives and enums
362 { 406 {
363 if (!as_generator( 407 if (!as_generator(
diff --git a/src/bindings/cxx/eina_cxx/eina_variant.hh b/src/bindings/cxx/eina_cxx/eina_variant.hh
index 358688a0bb..4885c80236 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/mono/efl_mono/efl_all.cs b/src/bindings/mono/efl_mono/efl_all.cs
index a8436bd8e5..d8c08d3890 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 21bb6c5967..0aa56908ff 100644
--- a/src/bindings/mono/efl_mono/efl_libs.cs.in
+++ b/src/bindings/mono/efl_mono/efl_libs.cs.in
@@ -17,6 +17,22 @@ public class Libs {
17 public const string Eldbus = "@ELDBUS_DL_MONO@"; 17 public const string Eldbus = "@ELDBUS_DL_MONO@";
18 18
19 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);
20} 36}
21 37
22} 38}
diff --git a/src/bindings/mono/eina_mono/eina_common.cs b/src/bindings/mono/eina_mono/eina_common.cs
index e2ddc70978..c9c10de160 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 bc2ce84a0c..3eddb2aa31 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)
@@ -539,6 +656,7 @@ public static class TraitFunctions
539 656
540 public static object RegisterTypeTraits<T>() 657 public static object RegisterTypeTraits<T>()
541 { 658 {
659 Eina.Log.Debug($"Finding TypeTraits for {typeof(T).Name}");
542 object traits; 660 object traits;
543 var type = typeof(T); 661 var type = typeof(T);
544 if (IsEflObject(type)) 662 if (IsEflObject(type))
@@ -549,13 +667,25 @@ public static class TraitFunctions
549 traits = new EflObjectElementTraits<T>(concrete); 667 traits = new EflObjectElementTraits<T>(concrete);
550 } 668 }
551 else if (IsString(type)) 669 else if (IsString(type))
552 traits = new StringElementTraits<T>(); 670 traits = new StringElementTraits();
553 else if (type.IsValueType) 671 else if (type.IsValueType)
554 { 672 {
555 if (Marshal.SizeOf<T>() <= 4) 673 if (type == typeof(int))
556 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();
557 else 687 else
558 traits = new Primitive64ElementTraits<T>(); 688 throw new Exception("No traits registered for this type");
559 } 689 }
560 else 690 else
561 throw new Exception("No traits registered for this type"); 691 throw new Exception("No traits registered for this type");
@@ -589,14 +719,9 @@ public static class TraitFunctions
589 return GetTypeTraits<T>().ManagedToNativeAlloc(man); 719 return GetTypeTraits<T>().ManagedToNativeAlloc(man);
590 } 720 }
591 721
592 public static IntPtr ManagedToNativeAllocRef<T>(T man, bool refs = false) 722 public static void ManagedToNativeCopyTo<T>(T man, IntPtr mem)
593 { 723 {
594 return GetTypeTraits<T>().ManagedToNativeAllocRef(man, refs); 724 GetTypeTraits<T>().ManagedToNativeCopyTo(man, mem);
595 }
596
597 public static IntPtr ManagedToNativeAllocInplace<T>(T man)
598 {
599 return GetTypeTraits<T>().ManagedToNativeAllocInplace(man);
600 } 725 }
601 726
602 public static IntPtr ManagedToNativeAllocInlistNode<T>(T man) 727 public static IntPtr ManagedToNativeAllocInlistNode<T>(T man)
@@ -609,11 +734,6 @@ public static class TraitFunctions
609 GetTypeTraits<T>().NativeFree(nat); 734 GetTypeTraits<T>().NativeFree(nat);
610 } 735 }
611 736
612 public static void NativeFreeRef<T>(IntPtr nat, bool unrefs = false)
613 {
614 GetTypeTraits<T>().NativeFreeRef(nat, unrefs);
615 }
616
617 public static void NativeFreeInlistNodeElement<T>(IntPtr nat) 737 public static void NativeFreeInlistNodeElement<T>(IntPtr nat)
618 { 738 {
619 GetTypeTraits<T>().NativeFreeInlistNodeElement(nat); 739 GetTypeTraits<T>().NativeFreeInlistNodeElement(nat);
@@ -639,11 +759,6 @@ public static class TraitFunctions
639 return GetTypeTraits<T>().NativeToManaged(nat); 759 return GetTypeTraits<T>().NativeToManaged(nat);
640 } 760 }
641 761
642 public static T NativeToManagedRef<T>(IntPtr nat)
643 {
644 return GetTypeTraits<T>().NativeToManagedRef(nat);
645 }
646
647 public static T NativeToManagedInlistNode<T>(IntPtr nat) 762 public static T NativeToManagedInlistNode<T>(IntPtr nat)
648 { 763 {
649 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 590033e7ab..4770870c69 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,14 +339,82 @@ 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);
333 NativeFree<TValue>(old); 415 IntPtr old = eina_hash_set(Handle, nk, nv);
416 FreeNativeIndirection<TKey>(gchnk, ForceRefKey<TKey>());
417 FreeNativeIndirection<TValue>(gchnv, false);
334 } 418 }
335 419
336 public TValue this[TKey key] 420 public TValue this[TKey key]
@@ -347,11 +431,17 @@ public class Hash<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>, IDi
347 431
348 public bool Move(TKey key_old, TKey key_new) 432 public bool Move(TKey key_old, TKey key_new)
349 { 433 {
350 var nk_old = ManagedToNativeAllocRef(key_old); 434 IntPtr gchnko = CopyNativeObject(key_old, ForceRefKey<TKey>());
351 var nk_new = ManagedToNativeAllocRef(key_new, true); 435 IntPtr nko = GetNativePtr<TKey>(gchnko, ForceRefKey<TKey>());
352 var r = eina_hash_move(Handle, nk_old, nk_new); 436 IntPtr gchnk = CopyNativeObject(key_new, ForceRefKey<TKey>());
353 NativeFreeRef<TKey>(nk_old, OwnKey && r); 437 IntPtr nk = GetNativePtr<TKey>(gchnk, ForceRefKey<TKey>());
354 NativeFreeRef<TKey>(nk_new, !r); 438 // var nk_old = ManagedToNativeAllocRef(key_old);
439 // var nk_new = ManagedToNativeAllocRef(key_new, true);
440 var r = eina_hash_move(Handle, nko, nk);
441 FreeNativeIndirection<TKey>(gchnko, ForceRefKey<TKey>());
442 FreeNativeIndirection<TKey>(gchnk, ForceRefKey<TKey>());
443 // NativeFreeRef<TKey>(nk_old, OwnKey && r);
444 // NativeFreeRef<TKey>(nk_new, !r);
355 return r; 445 return r;
356 } 446 }
357 447
@@ -383,7 +473,8 @@ public class Hash<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>, IDi
383 for (IntPtr tuplePtr; eina_iterator_next(itr, out tuplePtr);) 473 for (IntPtr tuplePtr; eina_iterator_next(itr, out tuplePtr);)
384 { 474 {
385 var tuple = Marshal.PtrToStructure<Eina.HashTupleNative>(tuplePtr); 475 var tuple = Marshal.PtrToStructure<Eina.HashTupleNative>(tuplePtr);
386 var key = NativeToManagedRef<TKey>(tuple.key); 476 IntPtr ikey = IndirectNative<TKey>(tuple.key, ForceRefKey<TKey>());
477 var key = NativeToManaged<TKey>(ikey);
387 var val = NativeToManaged<TValue>(tuple.data); 478 var val = NativeToManaged<TValue>(tuple.data);
388 yield return new KeyValuePair<TKey, TValue>(key, val); 479 yield return new KeyValuePair<TKey, TValue>(key, val);
389 } 480 }
diff --git a/src/bindings/mono/eina_mono/eina_inarray.cs b/src/bindings/mono/eina_mono/eina_inarray.cs
index d81f2ad239..47a1336b98 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
@@ -220,6 +226,7 @@ public class Inarray<T> : IEnumerable<T>, IDisposable
220 public T Nth(uint idx) 226 public T Nth(uint idx)
221 { 227 {
222 IntPtr ele = eina_inarray_nth(Handle, idx); 228 IntPtr ele = eina_inarray_nth(Handle, idx);
229 IntPtr v = Marshal.ReadIntPtr(ele);
223 return NativeToManagedInplace<T>(ele); 230 return NativeToManagedInplace<T>(ele);
224 } 231 }
225 232
@@ -230,8 +237,13 @@ public class Inarray<T> : IEnumerable<T>, IDisposable
230 237
231 public bool InsertAt(uint idx, T val) 238 public bool InsertAt(uint idx, T val)
232 { 239 {
233 IntPtr ele = ManagedToNativeAllocInplace(val); 240 IntPtr ele = IntPtr.Zero;
234 var r = eina_inarray_insert_at(Handle, idx, ele); 241 GCHandle gch = GCHandle.Alloc(ele, GCHandleType.Pinned);
242 IntPtr ind = gch.AddrOfPinnedObject();
243
244 ManagedToNativeCopyTo(val, ind);
245
246 var r = eina_inarray_insert_at(Handle, idx, ind);
235 if (!r) 247 if (!r)
236 NativeFreeInplace<T>(ele); 248 NativeFreeInplace<T>(ele);
237 ResidueFreeInplace<T>(ele); 249 ResidueFreeInplace<T>(ele);
@@ -245,8 +257,13 @@ public class Inarray<T> : IEnumerable<T>, IDisposable
245 return false; 257 return false;
246 if (OwnContent) 258 if (OwnContent)
247 NativeFreeInplace<T>(old); 259 NativeFreeInplace<T>(old);
248 var ele = ManagedToNativeAllocInplace(val); 260 var ele = IntPtr.Zero;
249 var r = eina_inarray_replace_at(Handle, idx, ele); 261 GCHandle gch = GCHandle.Alloc(ele, GCHandleType.Pinned);
262 IntPtr ind = gch.AddrOfPinnedObject();
263
264 ManagedToNativeCopyTo(val, ind);
265
266 var r = eina_inarray_replace_at(Handle, idx, ind);
250 ResidueFreeInplace<T>(ele); 267 ResidueFreeInplace<T>(ele);
251 return r; 268 return r;
252 } 269 }
diff --git a/src/bindings/mono/eo_mono/FunctionWrapper.cs b/src/bindings/mono/eo_mono/FunctionWrapper.cs
new file mode 100644
index 0000000000..448403a899
--- /dev/null
+++ b/src/bindings/mono/eo_mono/FunctionWrapper.cs
@@ -0,0 +1,95 @@
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 private NativeModule module; // so it doesn't get unloaded
29
30 private static FunctionLoadResult<T> LazyInitialization(NativeModule module, string functionName)
31 {
32 if (module.Module == IntPtr.Zero)
33 return new FunctionLoadResult<T>(FunctionLoadResultKind.LibraryNotFound);
34 else
35 {
36 IntPtr funcptr = FunctionInterop.LoadFunctionPointer(module.Module, functionName);
37 if (funcptr == IntPtr.Zero)
38 return new FunctionLoadResult<T>(FunctionLoadResultKind.FunctionNotFound);
39 else
40 return new FunctionLoadResult<T>(Marshal.GetDelegateForFunctionPointer<T>(funcptr));
41 }
42 }
43
44 public FunctionWrapper(string moduleName, string functionName)
45 : this (new NativeModule(moduleName), functionName)
46 {
47 }
48
49 public FunctionWrapper(NativeModule module, string functionName)
50 {
51 this.module = module;
52 loadResult = new Lazy<FunctionLoadResult<T>>
53 (() =>
54 {
55 return LazyInitialization(module, functionName);
56 });
57 }
58
59 public FunctionLoadResult<T> Value
60 {
61 get
62 {
63 return loadResult.Value;
64 }
65 }
66}
67
68public enum FunctionLoadResultKind { Success, LibraryNotFound, FunctionNotFound }
69
70public class FunctionLoadResult<T>
71{
72 public FunctionLoadResultKind Kind;
73 public T _Delegate;
74 public T Delegate
75 {
76 get {
77 if (_Delegate == null)
78 throw new InvalidOperationException($"Trying to get Delegate while not loaded. Load result: {Kind}");
79 return _Delegate;
80 }
81 }
82
83 public FunctionLoadResult(FunctionLoadResultKind kind)
84 {
85 this.Kind = kind;
86 }
87 public FunctionLoadResult(T Delegate)
88 {
89 this._Delegate = Delegate;
90 this.Kind = FunctionLoadResultKind.Success;
91 }
92}
93
94
95} }
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 0000000000..76ee4892ef
--- /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 0000000000..3cdd80cf2f
--- /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 0000000000..324a933b65
--- /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 0000000000..6f6939546c
--- /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 0000000000..889adc0949
--- /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 5388116065..744421503b 100644
--- a/src/bindings/mono/eo_mono/iwrapper.cs
+++ b/src/bindings/mono/eo_mono/iwrapper.cs
@@ -12,19 +12,40 @@ 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
28 [DllImport(efl.Libs.Eo)] public static extern IntPtr 49 [DllImport(efl.Libs.Eo)] public static extern IntPtr
29 efl_class_name_get(IntPtr eo); 50 efl_class_name_get(IntPtr eo);
30 [DllImport(efl.Libs.Eo)] public static extern IntPtr 51 [DllImport(efl.Libs.Eo)] public static extern IntPtr
@@ -125,30 +146,42 @@ public class Globals {
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 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);
126 [DllImport(efl.Libs.Eo)] public static extern IntPtr 147 [DllImport(efl.Libs.Eo)] public static extern IntPtr
127 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);
128 [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);
129 [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);
130 [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);
131 [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);
132#if WIN32 158 public delegate IntPtr dlerror_delegate();
133 public static IntPtr RTLD_DEFAULT = new IntPtr(1);
134#else
135 public static IntPtr RTLD_DEFAULT = new IntPtr(0);
136#endif
137 [DllImport(efl.Libs.Evil)] public static extern IntPtr dlerror(); 159 [DllImport(efl.Libs.Evil)] public static extern IntPtr dlerror();
138 [DllImport(efl.Libs.Evil)] public static extern IntPtr dlsym
139 (IntPtr handle, [MarshalAs(UnmanagedType.LPStr)] String name);
140 160
141 [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(
142 System.IntPtr obj, 168 System.IntPtr obj,
143 IntPtr desc, 169 IntPtr desc,
144 short priority, 170 short priority,
145 Efl.EventCb cb, 171 Efl.EventCb cb,
146 System.IntPtr data); 172 System.IntPtr data);
147 [DllImport(efl.Libs.Eo)] public static extern bool efl_event_callback_del( 173 public delegate bool efl_event_callback_del_delegate(
148 System.IntPtr obj, 174 System.IntPtr obj,
149 IntPtr desc, 175 IntPtr desc,
150 Efl.EventCb cb, 176 Efl.EventCb cb,
151 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);
152 [DllImport(efl.Libs.Eo)] public static extern IntPtr 185 [DllImport(efl.Libs.Eo)] public static extern IntPtr
153 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);
154 187
@@ -240,7 +273,7 @@ public class Globals {
240 } 273 }
241 public static byte class_initializer_call(IntPtr klass, System.Type type) 274 public static byte class_initializer_call(IntPtr klass, System.Type type)
242 { 275 {
243 Eina.Log.Debug($"called with 0x{klass.ToInt64()} {type}"); 276 Eina.Log.Debug($"called with 0x{klass.ToInt64():x} {type}");
244 Efl.Eo.NativeClass nativeClass = get_native_class(type.BaseType); 277 Efl.Eo.NativeClass nativeClass = get_native_class(type.BaseType);
245 278
246 if (nativeClass != null) 279 if (nativeClass != null)
@@ -259,7 +292,7 @@ public class Globals {
259 if(nc != null) 292 if(nc != null)
260 { 293 {
261 var moredescs = nc.GetEoOps(type); 294 var moredescs = nc.GetEoOps(type);
262 Eina.Log.Debug("adding {moredescs.Count} more descs to registration"); 295 Eina.Log.Debug($"adding {moredescs.Count} more descs to registration");
263 descs.AddRange(moredescs); 296 descs.AddRange(moredescs);
264 count = descs.Count; 297 count = descs.Count;
265 } 298 }
@@ -278,7 +311,7 @@ public class Globals {
278 ops.count = (UIntPtr)count; 311 ops.count = (UIntPtr)count;
279 IntPtr ops_ptr = Marshal.AllocHGlobal(Marshal.SizeOf(ops)); 312 IntPtr ops_ptr = Marshal.AllocHGlobal(Marshal.SizeOf(ops));
280 Marshal.StructureToPtr(ops, ops_ptr, false); 313 Marshal.StructureToPtr(ops, ops_ptr, false);
281 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);
282 //EoKlass = klass; 315 //EoKlass = klass;
283 } 316 }
284 else 317 else
@@ -391,38 +424,6 @@ public class Globals {
391 return null; 424 return null;
392 } 425 }
393 426
394 public static IntPtr cached_string_to_intptr(Dictionary<String, IntPtr> dict, String str)
395 {
396 IntPtr ptr = IntPtr.Zero;
397
398 if (str == null)
399 return ptr;
400
401 if (!dict.TryGetValue(str, out ptr))
402 {
403 ptr = Eina.StringConversion.ManagedStringToNativeUtf8Alloc(str);
404 dict[str] = ptr;
405 }
406
407 return ptr;
408 }
409
410 public static IntPtr cached_stringshare_to_intptr(Dictionary<String, IntPtr> dict, String str)
411 {
412 IntPtr ptr = IntPtr.Zero;
413
414 if (str == null)
415 return ptr;
416
417 if (!dict.TryGetValue(str, out ptr))
418 {
419 ptr = Eina.Stringshare.eina_stringshare_add(str);
420 dict[str] = ptr;
421 }
422
423 return ptr;
424 }
425
426 public static void free_dict_values(Dictionary<String, IntPtr> dict) 427 public static void free_dict_values(Dictionary<String, IntPtr> dict)
427 { 428 {
428 foreach(IntPtr ptr in dict.Values) 429 foreach(IntPtr ptr in dict.Values)
diff --git a/src/bindings/mono/eo_mono/meson.build b/src/bindings/mono/eo_mono/meson.build
index 4fbdf51360..8aca4004df 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 99fb53b7e4..4d576771f8 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 ed6f91b3d4..d14d5ad50d 100644
--- a/src/bindings/mono/meson.build
+++ b/src/bindings/mono/meson.build
@@ -1,5 +1,31 @@
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
11runtime_assemblies += [
12 'System.Console',
13 'Microsoft.CSharp',
14 'System.Collections',
15 'System.Collections.Concurrent',
16 'System.ComponentModel.Primitives',
17 'System.ComponentModel.Primitives',
18 'System.Diagnostics.Debug',
19 'System.Diagnostics.TraceSource',
20 'System.Dynamic.Runtime',
21 'System.Linq',
22 'System.Runtime',
23 'System.Runtime.Extensions',
24 'System.Security',
25]
26
27endif
28
3mono_sublibs = [ 29mono_sublibs = [
4 ['Eina', true, ], # 30 ['Eina', true, ], #
5 ['Eolian', true, ], # 31 ['Eolian', true, ], #
@@ -114,15 +140,24 @@ efl_mono_conf_data.set('EVAS', evas_lib.full_path())
114efl_mono_conf_data.set('ELDBUS', eldbus_lib.full_path()) 140efl_mono_conf_data.set('ELDBUS', eldbus_lib.full_path())
115efl_mono_conf_data.set('ELEMENTARY', elementary_lib.full_path()) 141efl_mono_conf_data.set('ELEMENTARY', elementary_lib.full_path())
116 142
117configure_file(input : 'efl_mono.dll.config.in', 143efl_mono_dll_config = configure_file(input : 'efl_mono.dll.config.in',
118 output : 'efl_mono.dll.config', 144 output : 'efl_mono.dll.config',
119 configuration : efl_mono_conf_data) 145 configuration : efl_mono_conf_data)
120 146
147if (cs_is_dotnet)
148efl_mono = library('efl_mono',
149 mono_generator_target + mono_files + [efl_src],
150 install : true,
151 install_dir : join_paths(dir_lib, 'efl-mono-'+version_major),
152 runtime_assemblies : runtime_assemblies
153)
154else
121efl_mono = library('efl_mono', 155efl_mono = library('efl_mono',
122 mono_generator_target + mono_files + [efl_src], 156 mono_generator_target + mono_files + [efl_src],
123 install : true, 157 install : true,
124 install_dir : join_paths(dir_lib, 'efl-mono-'+version_major) 158 install_dir : join_paths(dir_lib, 'efl-mono-'+version_major),
125) 159)
160endif
126 161
127efl_mono_test_suite_path=join_paths(meson.current_build_dir()) 162efl_mono_test_suite_path=join_paths(meson.current_build_dir())
128 163
diff --git a/src/lib/eolian_cxx/grammar/klass_def.hpp b/src/lib/eolian_cxx/grammar/klass_def.hpp
index cba2fb1079..9969e89075 100644
--- a/src/lib/eolian_cxx/grammar/klass_def.hpp
+++ b/src/lib/eolian_cxx/grammar/klass_def.hpp
@@ -16,6 +16,8 @@
16#include <vector> 16#include <vector>
17#include <memory> 17#include <memory>
18#include <set> 18#include <set>
19#include <iosfwd>
20#include <string>
19 21
20namespace efl { namespace eolian { namespace grammar { 22namespace efl { namespace eolian { namespace grammar {
21 23
@@ -73,6 +75,26 @@ enum class typedecl_type
73 function_ptr, 75 function_ptr,
74}; 76};
75 77
78inline std::ostream& operator<<(std::ostream& s, typedecl_type dec)
79{
80 switch(dec)
81 {
82 case typedecl_type::unknown:
83 return s << "unknown";
84 case typedecl_type::struct_:
85 return s << "struct_";
86 case typedecl_type::struct_opaque:
87 return s << "struct_opaque";
88 case typedecl_type::enum_:
89 return s << "enum_";
90 case typedecl_type::alias:
91 return s << "alias";
92 case typedecl_type::function_ptr:
93 return s << "function_ptr";
94 };
95 return s;
96}
97
76inline typedecl_type typedecl_type_get(Eolian_Typedecl const* decl) 98inline typedecl_type typedecl_type_get(Eolian_Typedecl const* decl)
77{ 99{
78 if (!decl) 100 if (!decl)
@@ -108,6 +130,22 @@ enum class class_type
108 regular, abstract_, mixin, interface_ 130 regular, abstract_, mixin, interface_
109}; 131};
110 132
133inline std::ostream& operator<<(std::ostream& s, class_type t)
134{
135 switch(t)
136 {
137 case class_type::regular:
138 return s << "regular";
139 case class_type::abstract_:
140 return s << "abstract_";
141 case class_type::mixin:
142 return s << "mixin";
143 case class_type::interface_:
144 return s << "interface_";
145 };
146 return s;
147}
148
111struct klass_name 149struct klass_name
112{ 150{
113 std::vector<std::string> namespaces; 151 std::vector<std::string> namespaces;
@@ -116,6 +154,14 @@ struct klass_name
116 class_type type; 154 class_type type;
117 std::string klass_get_name; 155 std::string klass_get_name;
118 156
157 friend inline std::ostream& operator<<(std::ostream& s, klass_name const& name)
158 {
159 s << "[ namespaces: {";
160 std::copy(name.namespaces.begin(), name.namespaces.end(), std::ostream_iterator<std::string>(s, ","));
161 return s << "}, eolian_name: " << name.eolian_name << " base_qualifier: " << name.base_qualifier
162 << " type: " << name.type << " klass_get_name: " << name.klass_get_name << "]";
163 }
164
119 klass_name() { 165 klass_name() {
120 } 166 }
121 167
@@ -272,6 +318,14 @@ struct regular_type_def
272 bool is_alias() const { return is_type(typedecl_type::alias); } 318 bool is_alias() const { return is_type(typedecl_type::alias); }
273 bool is_function_ptr() const { return is_type(typedecl_type::function_ptr); } 319 bool is_function_ptr() const { return is_type(typedecl_type::function_ptr); }
274 320
321 friend inline std::ostream& operator<<(std::ostream& s, regular_type_def const& def)
322 {
323 s << "[ base_type: " << def.base_type << " base_qualifier: " << def.base_qualifier
324 << " namespaces: ";
325 std::copy(def.namespaces.begin(), def.namespaces.end(), std::ostream_iterator<std::string>(s, ", "));
326 return s << " type_type: " << def.type_type << " is_undefined " << def.is_undefined << "]";
327 }
328
275 std::string base_type; 329 std::string base_type;
276 qualifier_def base_qualifier; 330 qualifier_def base_qualifier;
277 std::vector<std::string> namespaces; 331 std::vector<std::string> namespaces;
@@ -292,6 +346,13 @@ struct complex_type_def
292{ 346{
293 regular_type_def outer; 347 regular_type_def outer;
294 std::vector<type_def> subtypes; 348 std::vector<type_def> subtypes;
349
350 friend inline std::ostream& operator<<(std::ostream& s, complex_type_def const& def)
351 {
352 s << "[ outer " << def.outer << " subtypes: {";
353 std::copy(def.subtypes.begin(), def.subtypes.end(), std::ostream_iterator<type_def>(s, ", "));
354 return s << "}]";
355 }
295}; 356};
296 357
297inline bool operator==(complex_type_def const& lhs, complex_type_def const& rhs) 358inline bool operator==(complex_type_def const& lhs, complex_type_def const& rhs)
@@ -326,6 +387,12 @@ struct type_def
326 { 387 {
327 return lhs.c_type < rhs.c_type; 388 return lhs.c_type < rhs.c_type;
328 } 389 }
390 friend inline std::ostream& operator<<(std::ostream& s, type_def const& rhs)
391 {
392 return s << "[ original: " << rhs.original_type << " c_type "
393 << rhs.c_type << " has_own " << rhs.has_own << " is_ptr "
394 << rhs.is_ptr << "]";
395 }
329}; 396};
330 397
331struct get_qualifier_visitor 398struct get_qualifier_visitor
diff --git a/src/tests/efl_mono/Eo.cs b/src/tests/efl_mono/Eo.cs
index c31c1ad219..e955888a53 100644
--- a/src/tests/efl_mono/Eo.cs
+++ b/src/tests/efl_mono/Eo.cs
@@ -10,6 +10,13 @@ class TestEo
10 { 10 {
11 } 11 }
12 12
13 public static void return_null_object()
14 {
15 var testing = new Dummy.TestObject();
16 var o1 = testing.ReturnNullObject();
17 Test.Assert(o1 == null);
18 }
19
13 // 20 //
14 // Test cases: 21 // Test cases:
15 // 22 //
diff --git a/src/tests/efl_mono/dummy_test_object.eo b/src/tests/efl_mono/dummy_test_object.eo
index 72750fb140..517c783fe1 100644
--- a/src/tests/efl_mono/dummy_test_object.eo
+++ b/src/tests/efl_mono/dummy_test_object.eo
@@ -112,6 +112,10 @@ class Dummy.Test_Object extends Efl.Object implements Efl.Part, Dummy.Test_Iface
112 return: Dummy.Test_Object; 112 return: Dummy.Test_Object;
113 } 113 }
114 114
115 return_null_object {
116 return: Dummy.Test_Object;
117 }
118
115 int_out { 119 int_out {
116 params { 120 params {
117 @in x: int; 121 @in x: int;
diff --git a/src/tests/efl_mono/efl-mono-suite.runtimeconfig.json b/src/tests/efl_mono/efl-mono-suite.runtimeconfig.json
new file mode 100644
index 0000000000..0773dae0a0
--- /dev/null
+++ b/src/tests/efl_mono/efl-mono-suite.runtimeconfig.json
@@ -0,0 +1,10 @@
1{
2 "runtimeOptions": {
3 "tfm": "netcoreapp2.0",
4 "framework": {
5 "name": "Microsoft.NETCore.App",
6 "version": "2.0.0"
7 }
8 }
9}
10
diff --git a/src/tests/efl_mono/libefl_mono_native_test.c b/src/tests/efl_mono/libefl_mono_native_test.c
index 1769c61f89..8c17e05dd9 100644
--- a/src/tests/efl_mono/libefl_mono_native_test.c
+++ b/src/tests/efl_mono/libefl_mono_native_test.c
@@ -162,6 +162,11 @@ Efl_Object *_dummy_test_object_return_object(Eo *obj, EINA_UNUSED Dummy_Test_Obj
162 return obj; 162 return obj;
163} 163}
164 164
165Efl_Object *_dummy_test_object_return_null_object(Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd)
166{
167 return NULL;
168}
169
165void _dummy_test_object_int_out(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd, int x, int *y) 170void _dummy_test_object_int_out(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd, int x, int *y)
166{ 171{
167 *y = -x; 172 *y = -x;
diff --git a/src/tests/efl_mono/meson.build b/src/tests/efl_mono/meson.build
index a2c34e3699..c07e38fa3f 100644
--- a/src/tests/efl_mono/meson.build
+++ b/src/tests/efl_mono/meson.build
@@ -31,10 +31,18 @@ foreach mono_gen_file : eo_files
31 '@INPUT@']) 31 '@INPUT@'])
32endforeach 32endforeach
33 33
34if (cs_is_dotnet)
34efl_mono_test = library('efl_mono_test', 35efl_mono_test = library('efl_mono_test',
35 eo_file_targets, 36 eo_file_targets,
36 link_with : [efl_mono], 37 link_with : [efl_mono],
38 runtime_assemblies : runtime_assemblies
37) 39)
40else
41efl_mono_test = library('efl_mono_test',
42 eo_file_targets,
43 link_with : [efl_mono],
44)
45endif
38 46
39efl_mono_src = [ 47efl_mono_src = [
40 'Main.cs', 48 'Main.cs',
@@ -60,14 +68,43 @@ efl_mono_src = [
60 'Inheritance.cs', 68 'Inheritance.cs',
61] 69]
62 70
71if (cs_is_dotnet)
63efl_mono_suite = executable('efl-mono-suite', 72efl_mono_suite = executable('efl-mono-suite',
64 efl_mono_src, 73 efl_mono_src,
65 link_with : [efl_mono, efl_mono_test], 74 link_with : [efl_mono, efl_mono_test],
75 runtime_assemblies : runtime_assemblies
66) 76)
77else
78efl_mono_suite = executable('efl-mono-suite',
79 efl_mono_src,
80 link_with : [efl_mono, efl_mono_test],
81)
82endif
67 83
68env = environment() 84env = environment()
69env.set('MONO_PATH', efl_mono_test_suite_path ) 85env.set('MONO_PATH', efl_mono_test_suite_path )
70 86
87if (cs_is_dotnet)
88env.set('LD_LIBRARY_PATH', efl_mono_test_suite_path )
89copy_prog = find_program(['cp', 'copy'])
90
91configure_file(input : 'efl-mono-suite.runtimeconfig.json',
92 output : 'efl-mono-suite.runtimeconfig.json',
93 copy : true)
94
95custom_target('copy_efl_mono_dll',
96 build_by_default : true,
97 input : efl_mono,
98 output : efl_mono.full_path().split('/')[-1],
99 command : [copy_prog, '@INPUT@', '@OUTPUT@'])
100
101custom_target('copy_efl_mono_lib_dll',
102 build_by_default : true,
103 input : efl_mono_lib,
104 output : efl_mono_lib.full_path().split('/')[-1],
105 command : [copy_prog, '@INPUT@', '@OUTPUT@'])
106endif
107
71config_libs = ['eina', 'ecore', 'eo', 'efl', 'evas', 'eldbus', 'elementary'] 108config_libs = ['eina', 'ecore', 'eo', 'efl', 'evas', 'eldbus', 'elementary']
72load_lib = '' 109load_lib = ''
73 110