aboutsummaryrefslogtreecommitdiffstats
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
parentefl-mono: Add support for Efl.Class (diff)
downloadefl-f392c5a4363cf09e8c0e50a42c46416a09a72c74.tar.gz
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 https://phab.enlightenment.org/T7394 Reviewers: felipealmeida, vitor.sousa, bu5hm4n Reviewed By: vitor.sousa Subscribers: cedric Tags: #efl Maniphest Tasks: https://phab.enlightenment.org/T7394 Differential Revision: https://phab.enlightenment.org/D8069
-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 = \
efl_eo_mono_files = \
bindings/mono/eo_mono/iwrapper.cs \
+ bindings/mono/eo_mono/FunctionWrapper.cs \
+ bindings/mono/eo_mono/NativeModule.cs \
bindings/mono/eo_mono/workaround.cs
+if HAVE_WIN32
+
+efl_eo_mono_files += \
+ bindings/mono/eo_mono/FunctionWrapper_Windows.cs \
+ bindings/mono/eo_mono/NativeModule_Windows.cs
+
+else
+
+efl_eo_mono_files += \
+ bindings/mono/eo_mono/FunctionWrapper_Unix.cs \
+ bindings/mono/eo_mono/NativeModule_Unix.cs
+
+endif
+
+
efl_eina_mono_files = \
bindings/mono/eina_mono/eina_config.cs \
bindings/mono/eina_mono/eina_array.cs \
@@ -293,7 +310,7 @@ msbuildcsprojs: ../libefl_mono.csproj
done
### Some hard-coded runtime dependencies for tests and examples
-TEST_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
+TEST_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
WIN_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
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
bool generate_event_add_remove(OutputIterator sink, attributes::event_def const &evt, const std::string& event_name, Context context) const
{
std::string upper_c_name = utils::to_uppercase(evt.c_name);
+ auto unit = (const Eolian_Unit*) context_find_tag<eolian_state_context>(context).state;
+ attributes::klass_def klass(get_klass(evt.klass, unit), unit);
+ auto library_name = context_find_tag<library_context>(context).actual_library_name(klass.filename);
return as_generator(
scope_tab << "{\n"
<< scope_tab << scope_tab << "add {\n"
<< scope_tab << scope_tab << scope_tab << "lock (eventLock) {\n"
<< scope_tab << scope_tab << scope_tab << scope_tab << "string key = \"_" << upper_c_name << "\";\n"
- << scope_tab << scope_tab << scope_tab << scope_tab << "if (add_cpp_event_handler(key, this.evt_" << event_name << "_delegate)) {\n"
+ << scope_tab << scope_tab << scope_tab << scope_tab << "if (add_cpp_event_handler(" << library_name << ", key, this.evt_" << event_name << "_delegate)) {\n"
<< scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "eventHandlers.AddHandler(" << event_name << "Key , value);\n"
<< scope_tab << scope_tab << scope_tab << scope_tab << "} else\n"
<< 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
bool generate(OutputIterator sink, attributes::function_def const& f, Context const& context) const
{
EINA_CXX_DOM_LOG_DBG(eolian_mono::domain) << "native_function_definition_generator: " << f.c_name << std::endl;
- if(blacklist::is_function_blacklisted(f, context) || f.is_static) // Only Concrete classes implement static methods.
+ if(blacklist::is_function_blacklisted(f, context))
return true;
else
{
if(!as_generator
("\n\n" << scope_tab
- << eolian_mono::marshall_native_annotation(true)
+ << eolian_mono::marshall_annotation(true)
<< " private delegate "
<< eolian_mono::marshall_type(true)
<< " "
<< string
- << "_delegate(System.IntPtr obj, System.IntPtr pd"
- << *grammar::attribute_reorder<-1, -1>
+ << "_delegate(" << (f.is_static ? "" : "System.IntPtr obj, System.IntPtr pd")
+ << ((!f.is_static && f.parameters.size() > 0) ? ", " : "")
+ << (grammar::attribute_reorder<-1, -1>
(
- (", " << marshall_native_annotation << " " << marshall_parameter)
- )
+ (marshall_annotation << " " << marshall_parameter)
+ ) % ", ")
<< ");\n")
.generate(sink, std::make_tuple(f.return_type, f.return_type, f.c_name, f.parameters), context))
return false;
if(!as_generator
- (scope_tab << "[System.Runtime.InteropServices.DllImport(" << context_find_tag<library_context>(context).actual_library_name(f.filename) << ")] "
- << eolian_mono::marshall_native_annotation(true)
- << " private static extern "
+ ("\n\n" << scope_tab
+ << eolian_mono::marshall_annotation(true)
+ << " public delegate "
<< eolian_mono::marshall_type(true)
- << " " << string
- << "(System.IntPtr obj"
- << *grammar::attribute_reorder<-1, -1>
+ << " "
+ << string << "_api_delegate(" << (f.is_static ? "" : "System.IntPtr obj")
+ << ((!f.is_static && f.parameters.size() > 0) ? ", " : "")
+ << (grammar::attribute_reorder<-1, -1>
(
- (", " << marshall_native_annotation << " " << marshall_parameter)
- )
+ (marshall_annotation << " " << marshall_parameter)
+ ) % ", ")
<< ");\n")
.generate(sink, std::make_tuple(f.return_type, f.return_type, f.c_name, f.parameters), context))
return false;
+ if(!as_generator
+ (scope_tab
+ << " public static Efl.Eo.FunctionWrapper<" << string << "_api_delegate> " << string << "_ptr = new Efl.Eo.FunctionWrapper<"
+ << string << "_api_delegate>(_Module, \"" << string << "\");\n")
+ .generate(sink, std::make_tuple(f.c_name, f.c_name, f.c_name, f.c_name), context))
+ return false;
+
std::string return_type;
if(!as_generator(eolian_mono::type(true)).generate(std::back_inserter(return_type), f.return_type, context))
return false;
@@ -77,6 +86,11 @@ struct native_function_definition_generator
else
klass_cast_name = name_helpers::klass_interface_name(*klass);
+ std::string self = "Efl.Eo.Globals.efl_super(obj, Efl.Eo.Globals.efl_class_get(obj))";
+
+ if (f.is_static)
+ self = "";
+
if(!as_generator
(scope_tab
<< " private static "
@@ -93,7 +107,8 @@ struct native_function_definition_generator
<< scope_tab << scope_tab << "if(wrapper != null) {\n"
<< scope_tab << scope_tab << scope_tab << eolian_mono::native_function_definition_preamble()
<< scope_tab << scope_tab << scope_tab << "try {\n"
- << scope_tab << scope_tab << scope_tab << scope_tab << (return_type != " void" ? "_ret_var = " : "") << "((" << klass_cast_name << ")wrapper)." << string
+ << scope_tab << scope_tab << scope_tab << scope_tab << (return_type != " void" ? "_ret_var = " : "")
+ << (f.is_static ? "" : "((") << klass_cast_name << (f.is_static ? "." : ")wrapper).") << string
<< "(" << (native_argument_invocation % ", ") << ");\n"
<< scope_tab << scope_tab << scope_tab << "} catch (Exception e) {\n"
<< 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
<< eolian_mono::native_function_definition_epilogue(*klass)
<< scope_tab << scope_tab << "} else {\n"
<< scope_tab << scope_tab << scope_tab << (return_type != " void" ? "return " : "") << string
- << "(Efl.Eo.Globals.efl_super(obj, " << "Efl.Eo.Globals.efl_class_get(obj))" << *(", " << argument) << ");\n"
+ << "_ptr.Value.Delegate(" << self << ((!f.is_static && f.parameters.size() > 0) ? ", " : "") << (argument % ", ") << ");\n"
<< scope_tab << scope_tab << "}\n"
<< scope_tab << "}\n"
)
@@ -118,9 +133,13 @@ struct native_function_definition_generator
, context))
return false;
+ // Static functions do not need to be called from C
+ if (f.is_static)
+ return true;
+
// This is the delegate that will be passed to Eo to be called from C.
if(!as_generator(
- scope_tab << "private " << f.c_name << "_delegate " << f.c_name << "_static_delegate;\n"
+ scope_tab << "private static " << f.c_name << "_delegate " << f.c_name << "_static_delegate;\n"
).generate(sink, attributes::unused, context))
return false;
return true;
@@ -141,22 +160,6 @@ struct function_definition_generator
if(blacklist::is_function_blacklisted(f, context))
return true;
- if(!as_generator
- ("\n\n" << scope_tab << "[System.Runtime.InteropServices.DllImport(" << context_find_tag<library_context>(context).actual_library_name(f.filename) << ")]\n"
- << scope_tab << eolian_mono::marshall_annotation(true)
- << (do_super ? " protected " : " private ") << "static extern "
- << eolian_mono::marshall_type(true)
- << " " << string
- << "(" << (f.is_static ? "" : "System.IntPtr obj")
- << ((!f.is_static && (f.parameters.size() > 0)) ? ", " : "")
- << (grammar::attribute_reorder<-1, -1>
- (
- (marshall_annotation << " " << marshall_parameter)
- ) % ",")
- << ");\n")
- .generate(sink, std::make_tuple(f.return_type, f.return_type, f.c_name, f.parameters), context))
- return false;
-
std::string return_type;
if(!as_generator(eolian_mono::type(true)).generate(std::back_inserter(return_type), f.return_type, context))
return false;
@@ -176,8 +179,10 @@ struct function_definition_generator
if(!as_generator
(scope_tab << ((do_super && !f.is_static) ? "virtual " : "") << "public " << (f.is_static ? "static " : "") << return_type << " " << string << "(" << (parameter % ", ")
<< ") {\n "
- << eolian_mono::function_definition_preamble() << string << "("
- << self << ((!f.is_static && (f.parameters.size() > 0)) ? "," : "")
+ << eolian_mono::function_definition_preamble()
+ << klass_full_native_inherit_name(f.klass) << "." << string << "_ptr.Value.Delegate("
+ << self
+ << ((!f.is_static && (f.parameters.size() > 0)) ? "," : "")
<< (argument_invocation % ", ") << ");\n"
<< eolian_mono::function_definition_epilogue()
<< " }\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 {
.generate(sink, std::make_tuple(f, f.return_type, f_name, f.parameters), funcptr_ctx))
return false;
// "Internal" delegate, 1-to-1 with the Unamaged function type
- if (!as_generator(marshall_native_annotation(true)
+ if (!as_generator(marshall_annotation(true)
<< "public delegate " << marshall_type(true) << " " << string // public?
- << "Internal(IntPtr data" << *grammar::attribute_reorder<-1, -1>((", " << marshall_native_annotation << " " << marshall_parameter)) << ");\n")
+ << "Internal(IntPtr data" << *grammar::attribute_reorder<-1, -1>((", " << marshall_annotation << " " << marshall_parameter)) << ");\n")
.generate(sink, std::make_tuple(f.return_type, f.return_type, f_name, f.parameters), funcptr_ctx))
return false;
@@ -80,8 +80,8 @@ struct function_pointer {
<< scope_tab << "}\n\n"
- << scope_tab << marshall_native_annotation(true)
- << scope_tab << "internal static " << marshall_type(true) << " Cb(IntPtr cb_data" << *grammar::attribute_reorder<-1, -1>((", " << marshall_native_annotation << " " << marshall_parameter)) << ")\n"
+ << scope_tab << marshall_annotation(true)
+ << scope_tab << "internal static " << marshall_type(true) << " Cb(IntPtr cb_data" << *grammar::attribute_reorder<-1, -1>((", " << marshall_annotation << " " << marshall_parameter)) << ")\n"
<< scope_tab << "{\n"
<< scope_tab << scope_tab << "GCHandle handle = GCHandle.FromIntPtr(cb_data);\n"
<< 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
// auto index = index_generator();
if(!as_generator(
- scope_tab << scope_tab << f.c_name << "_static_delegate = new " << f.c_name << "_delegate(" <<
+ scope_tab << scope_tab << "if (" << f.c_name << "_static_delegate == null)\n"
+ << scope_tab << scope_tab << f.c_name << "_static_delegate = new " << f.c_name << "_delegate(" <<
escape_keyword(f.name) << ");\n"
).generate(sink, attributes::unused, context))
return false;
@@ -47,9 +48,9 @@ struct function_registration_generator
#ifdef _WIN32
<< "api_func = Marshal.StringToHGlobalAnsi(\"" << string << "\")"
#else
- << "api_func = Efl.Eo.Globals.dlsym(Efl.Eo.Globals.RTLD_DEFAULT, \"" << string << "\")"
+ << "api_func = Efl.Eo.FunctionInterop.LoadFunctionPointer(_Module.Module, \"" << string << "\")"
#endif
- ", func = Marshal.GetFunctionPointerForDelegate(" << string << "_static_delegate)});\n"
+ << ", func = Marshal.GetFunctionPointerForDelegate(" << string << "_static_delegate)});\n"
)
.generate(sink, std::make_tuple(f.c_name, f.c_name), context))
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
if(!as_generator
(
- "public class " << native_inherit_name << " " << (root ? ": Efl.Eo.NativeClass" : (": " + base_name)) <<"{\n"
- // << scope_tab << (root ? "protected IntPtr EoKlass { get; set; }\n" : "\n")
- << scope_tab << "public " << /*(root ? "" : "new ")*/ "override " << "System.Collections.Generic.List<Efl_Op_Description> GetEoOps(System.Type type)\n"
+ "public class " << native_inherit_name << " " << (root ? " : Efl.Eo.NativeClass" : (": " + base_name)) <<"{\n"
+ << scope_tab << "public " << (root ? "" : "new ") << " static Efl.Eo.NativeModule _Module = new Efl.Eo.NativeModule("
+ << context_find_tag<library_context>(context).actual_library_name(cls.filename) << ");\n"
+ << scope_tab << "public override System.Collections.Generic.List<Efl_Op_Description> GetEoOps(System.Type type)\n"
<< scope_tab << "{\n"
<< scope_tab << scope_tab << "var descs = new System.Collections.Generic.List<Efl_Op_Description>();\n"
)
@@ -488,8 +489,6 @@ struct klass
return as_generator(
scope_tab << visibility << " System.IntPtr handle;\n"
- << scope_tab << "public Dictionary<String, IntPtr> cached_strings = new Dictionary<String, IntPtr>();" << "\n"
- << scope_tab << "public Dictionary<String, IntPtr> cached_stringshares = new Dictionary<String, IntPtr>();" << "\n"
<< scope_tab << "///<summary>Pointer to the native instance.</summary>\n"
<< scope_tab << "public System.IntPtr NativeHandle {\n"
<< scope_tab << scope_tab << "get { return handle; }\n"
@@ -603,8 +602,6 @@ struct klass
<< scope_tab << "///<summary>Releases the underlying native instance.</summary>\n"
<< scope_tab << "public void Dispose()\n"
<< scope_tab << "{\n"
- << scope_tab << "Efl.Eo.Globals.free_dict_values(cached_strings);" << "\n"
- << scope_tab << "Efl.Eo.Globals.free_stringshare_values(cached_stringshares);" << "\n"
<< scope_tab << scope_tab << "Dispose(true);\n"
<< scope_tab << scope_tab << "GC.SuppressFinalize(this);\n"
<< scope_tab << "}\n"
@@ -681,13 +678,13 @@ struct klass
// Callback registration functions
if (!as_generator(
- scope_tab << visibility << "bool add_cpp_event_handler(string key, Efl.EventCb evt_delegate) {\n"
+ scope_tab << visibility << "bool add_cpp_event_handler(string lib, string key, Efl.EventCb evt_delegate) {\n"
<< scope_tab << scope_tab << "int event_count = 0;\n"
<< scope_tab << scope_tab << "if (!event_cb_count.TryGetValue(key, out event_count))\n"
<< scope_tab << scope_tab << scope_tab << "event_cb_count[key] = event_count;\n"
<< scope_tab << scope_tab << "if (event_count == 0) {\n"
- << scope_tab << scope_tab << scope_tab << "IntPtr desc = Efl.EventDescription.GetNative(key);\n"
+ << scope_tab << scope_tab << scope_tab << "IntPtr desc = Efl.EventDescription.GetNative(lib, key);\n"
<< scope_tab << scope_tab << scope_tab << "if (desc == IntPtr.Zero) {\n"
<< scope_tab << scope_tab << scope_tab << scope_tab << "Eina.Log.Error($\"Failed to get native event {key}\");\n"
<< scope_tab << scope_tab << scope_tab << scope_tab << "return false;\n"
@@ -709,7 +706,8 @@ struct klass
<< scope_tab << scope_tab << scope_tab << "event_cb_count[key] = event_count;\n"
<< scope_tab << scope_tab << "if (event_count == 1) {\n"
- << scope_tab << scope_tab << scope_tab << "IntPtr desc = Efl.EventDescription.GetNative(key);\n"
+ << scope_tab << scope_tab << scope_tab << "IntPtr desc = Efl.EventDescription.GetNative("
+ << context_find_tag<library_context>(context).actual_library_name(cls.filename) << ", key);\n"
<< scope_tab << scope_tab << scope_tab << "if (desc == IntPtr.Zero) {\n"
<< scope_tab << scope_tab << scope_tab << scope_tab << "Eina.Log.Error($\"Failed to get native event {key}\");\n"
<< 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
{"string", true, [&] {
return " [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringPassOwnershipMarshaler))]";
}},
- {"string", false, [&] {
+ {"string", nullptr, [&] {
return " [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringKeepOwnershipMarshaler))]";
}},
{"mstring", true, [&] {
@@ -112,10 +112,10 @@ struct marshall_annotation_visitor_generate
return " [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Eina.ValueMarshaler))]";
}},
{"strbuf", true, [&] {
- return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StrbufPassOwnershipMarshaler))]";
+ return " [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StrbufPassOwnershipMarshaler))]";
}},
{"strbuf", false, [&] {
- return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StrbufKeepOwnershipMarshaler))]";
+ return " [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StrbufKeepOwnershipMarshaler))]";
}},
};
@@ -169,128 +169,6 @@ struct marshall_annotation_visitor_generate
return true;
}
};
-
-template <typename OutputIterator, typename Context>
-struct marshall_native_annotation_visitor_generate
-{
- mutable OutputIterator sink;
- Context const* context;
- std::string c_type;
- bool is_out;
- bool is_return;
- bool is_ptr;
-
- typedef marshall_type_visitor_generate<OutputIterator, Context> visitor_type;
- typedef bool result_type;
-
- bool operator()(attributes::regular_type_def const& regular) const
- {
- using attributes::regular_type_def;
- struct match
- {
- eina::optional<std::string> name;
- eina::optional<bool> has_own;
- std::function<std::string()> function;
- };
- match const parameter_match_table[] =
- {
- // signed primitives
- {"bool", nullptr, [&] { return " [MarshalAs(UnmanagedType.U1)]"; }},
- {"string", true, [&] {
- return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringPassOwnershipMarshaler))]";
- }},
- {"string", false, [&] {
- if (is_out)
- return "";
- return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringKeepOwnershipMarshaler))]";
- }},
- {"stringshare", true, [&] {
- return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringsharePassOwnershipMarshaler))]";
- }},
- {"stringshare", false, [&] {
- if (is_out)
- return "";
- return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringshareKeepOwnershipMarshaler))]";
- }},
- {"strbuf", true, [&] {
- return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StrbufPassOwnershipMarshaler))]";
- }},
- {"strbuf", false, [&] {
- return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StrbufKeepOwnershipMarshaler))]";
- }},
- };
- match const return_match_table[] =
- {
- // signed primitives
- {"bool", nullptr, [&] { return " [return: MarshalAs(UnmanagedType.U1)]"; }},
- {"string", true, [&] {
- return " [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringPassOwnershipMarshaler))]";
- }},
- {"string", false, [&] { return ""; }},
- {"stringshare", true, [&] {
- return " [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringsharePassOwnershipMarshaler))]";
- }},
- {"stringshare", false, [&] { return ""; }},
- {"strbuf", true, [&] {
- return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StrbufPassOwnershipMarshaler))]";
- }},
- {"strbuf", false, [&] {
- return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StrbufKeepOwnershipMarshaler))]";
- }},
- };
-
- if(eina::optional<bool> b = call_annotation_match
- ((is_return ? return_match_table : parameter_match_table)
- , [&] (match const& m)
- {
- return (!m.name || *m.name == regular.base_type)
- && (!m.has_own || *m.has_own == (bool)(regular.base_qualifier & qualifier_info::is_own))
- ;
- }
- , [&] (std::string const& string)
- {
- std::copy(string.begin(), string.end(), sink);
- return true;
- }))
- {
- return *b;
- }
- else
- {
- return true;
- }
- }
- bool operator()(attributes::klass_name const& klass_name) const
- {
- const char *return_prefix = is_return ? "return:" : "";
- const char *marshal_prefix = "MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(";
-
- std::string name = name_helpers::klass_full_concrete_name(klass_name);
-
- if (name == "Efl.Class")
- name = "Efl.Eo.MarshalEflClass";
- else
- {
- auto own = klass_name.base_qualifier & qualifier_info::is_own ? "OwnTag" : "NonOwnTag";
- name = "Efl.Eo.MarshalTest<" + name + ", Efl.Eo." + own + ">";
- }
-
- return as_generator(
- lit("[") << return_prefix << marshal_prefix << name << "))]"
- ).generate(sink, name, *context);
- }
- bool operator()(attributes::complex_type_def const& c) const
- {
- if (c.outer.base_type == "future")
- {
- std::string prefix = is_return ? "return: " : "";
- return as_generator("[" << prefix << "MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Eina.FutureMarshaler))]").generate(sink, nullptr, *context);
- }
- return true;
- }
-};
-
-
} }
#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>
struct marshall_type_visitor_generate;
template <typename OutputIterator, typename Context>
struct marshall_annotation_visitor_generate;
-template <typename OutputIterator, typename Context>
-struct marshall_native_annotation_visitor_generate;
}
/*
@@ -73,26 +71,6 @@ struct marshall_annotation_generator
bool is_return;
};
-struct marshall_native_annotation_generator
-{
- marshall_native_annotation_generator(bool is_return = false)
- : is_return(is_return) {}
-
- template <typename OutputIterator, typename Context>
- bool generate(OutputIterator sink, attributes::type_def const& type, Context const& context) const
- {
- return type.original_type.visit(detail::marshall_native_annotation_visitor_generate<OutputIterator, Context>{sink, &context, type.c_type, false, is_return, type.is_ptr});
- }
- template <typename OutputIterator, typename Context>
- bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
- {
- return param.type.original_type.visit(detail::marshall_native_annotation_visitor_generate<OutputIterator, Context>{sink, &context, param.type.c_type
- , param.direction != attributes::parameter_direction::in, false, param.type.is_ptr});
- }
-
- bool is_return;
-};
-
struct marshall_type_terminal
{
marshall_type_generator const operator()(bool is_return) const
@@ -120,19 +98,6 @@ marshall_annotation_generator const as_generator(marshall_annotation_terminal)
}
-struct marshall_native_annotation_terminal
-{
- marshall_native_annotation_generator const operator()(bool is_return) const
- {
- return marshall_native_annotation_generator(is_return);
- }
-} const marshall_native_annotation = {};
-
-marshall_native_annotation_generator const as_generator(marshall_native_annotation_terminal)
-{
- return marshall_native_annotation_generator{};
-}
-
}
namespace efl { namespace eolian { namespace grammar {
@@ -158,23 +123,12 @@ struct is_generator< ::eolian_mono::marshall_annotation_generator> : std::true_t
template <>
struct is_generator< ::eolian_mono::marshall_annotation_terminal> : std::true_type {};
-template <>
-struct is_eager_generator< ::eolian_mono::marshall_native_annotation_generator> : std::true_type {};
-template <>
-struct is_generator< ::eolian_mono::marshall_native_annotation_generator> : std::true_type {};
-template <>
-struct is_generator< ::eolian_mono::marshall_native_annotation_terminal> : std::true_type {};
-
namespace type_traits {
template <>
struct attributes_needed< ::eolian_mono::marshall_annotation_generator> : std::integral_constant<int, 1> {};
template <>
struct attributes_needed< ::eolian_mono::marshall_annotation_terminal> : std::integral_constant<int, 1> {};
-template <>
-struct attributes_needed< ::eolian_mono::marshall_native_annotation_generator> : std::integral_constant<int, 1> {};
-template <>
-struct attributes_needed< ::eolian_mono::marshall_native_annotation_terminal> : std::integral_constant<int, 1> {};
}
} } }
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
bool operator()(attributes::regular_type_def const& regular) const
{
using attributes::regular_type_def;
- bool is_inherit_native = context_find_tag<class_context>(*context).current_wrapper_kind == class_context::inherit_native;
struct match
{
@@ -47,32 +46,24 @@ struct marshall_type_visitor_generate
{
regular_type_def r = regular;
r.base_qualifier.qualifier ^= qualifier_info::is_ref;
- // if(is_out || is_return)
return replace_base_type(r, " System.String");
- // else return replace_base_type(r, " ::efl::eina::string_view");
}}
, {"string", false, [&]
{
regular_type_def r = regular;
r.base_qualifier.qualifier ^= qualifier_info::is_ref;
- if (is_inherit_native && (is_return || is_out))
- return replace_base_type(r, " System.IntPtr");
return replace_base_type(r, " System.String");
}}
, {"mstring", true, [&]
{
regular_type_def r = regular;
r.base_qualifier.qualifier ^= qualifier_info::is_ref;
- // if(is_out || is_return)
return replace_base_type(r, " System.String");
- // else return replace_base_type(r, " ::efl::eina::string_view");
}}
, {"mstring", false, [&]
{
regular_type_def r = regular;
r.base_qualifier.qualifier ^= qualifier_info::is_ref;
- if (is_inherit_native && (is_return || is_out))
- return replace_base_type(r, " System.IntPtr");
return replace_base_type(r, " System.String");
}}
, {"stringshare", true, [&]
@@ -85,10 +76,7 @@ struct marshall_type_visitor_generate
{
regular_type_def r = regular;
r.base_qualifier.qualifier ^= qualifier_info::is_ref;
- if (is_inherit_native && (is_return || is_out))
- return replace_base_type(r, " System.IntPtr");
- else
- return replace_base_type(r, " System.String");
+ return replace_base_type(r, " System.String");
}}
, {"strbuf", nullptr, [&]
{
@@ -193,7 +181,6 @@ struct marshall_type_visitor_generate
bool operator()(attributes::klass_name klass_name) const
{
return visitor_generate<OutputIterator, Context>{sink, context, c_type, is_out, is_return, is_ptr}(klass_name);
- // return as_generator(" System.IntPtr").generate(sink, attributes::unused, *context);
}
bool operator()(attributes::complex_type_def const& complex) const
{
@@ -237,14 +224,8 @@ struct marshall_type_visitor_generate
auto default_match = [&] (attributes::complex_type_def const& complex)
{
regular_type_def no_pointer_regular = complex.outer;
- // std::vector<attributes::pointer_indirection> pointers;
- // pointers.swap(no_pointer_regular.pointers);
- // if(is_out)
- // pointers.push_back({{attributes::qualifier_info::is_none, {}}, true});
return visitor_type{sink, context, c_type, false}(no_pointer_regular)
- && as_generator("<" << (type % ", ") << ">").generate(sink, complex.subtypes, *context)
- ;
- // && detail::generate_pointers(sink, pointers, *context, false);
+ && as_generator("<" << (type % ", ") << ">").generate(sink, complex.subtypes, *context);
};
if(eina::optional<bool> b = call_match
@@ -269,12 +250,9 @@ struct marshall_type_visitor_generate
return *b;
}
- //return default_match(complex);
return visitor_generate<OutputIterator, Context>{sink, context, c_type, is_out, is_return, is_ptr}(complex);
- // return as_generator(" System.IntPtr").generate(sink, attributes::unused, *context);
}
};
-
} }
#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)
template<typename T>
inline std::string klass_native_inherit_name(T const& klass)
{
- return klass_concrete_name(klass) + "NativeInherit";
+ switch(klass.type)
+ {
+ case attributes::class_type::abstract_:
+ case attributes::class_type::regular:
+ return klass_concrete_name(klass) + "NativeInherit";
+ default:
+ return klass_interface_name(klass) + "NativeInherit";
+ }
}
template<typename T>
inline std::string klass_full_native_inherit_name(T const& klass)
{
- return klass_full_concrete_name(klass) + "NativeInherit";
+ switch(klass.type)
+ {
+ case attributes::class_type::abstract_:
+ case attributes::class_type::regular:
+ return klass_full_concrete_name(klass) + "NativeInherit";
+ default:
+ return klass_full_interface_name(klass) + "NativeInherit";
+ }
}
template<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
return false;
}
return as_generator(
- string << "= Efl.Eo.Globals.cached_stringshare_to_intptr(((" << name_helpers::klass_inherit_name(*klass) << ")wrapper).cached_stringshares, " << string << ");\n"
+ string << "= " << string << ";\n"
).generate(sink, std::make_tuple(escape_keyword(param.param_name), out_variable_name(param.param_name)), context);
}
else if (param_is_acceptable(param, "const char *", !WANT_OWN, WANT_OUT))
@@ -1123,7 +1123,7 @@ struct native_convert_out_assign_generator
return false;
}
return as_generator(
- string << "= Efl.Eo.Globals.cached_string_to_intptr(((" << name_helpers::klass_inherit_name(*klass) << ")wrapper).cached_strings, " << string << ");\n"
+ string << " = " << string << ";\n"
).generate(sink, std::make_tuple(escape_keyword(param.param_name), out_variable_name(param.param_name)), context);
}
else if (param_is_acceptable(param, "Eina_Binbuf *", WANT_OWN, WANT_OUT)
@@ -1253,7 +1253,7 @@ struct native_convert_return_generator
return false;
}
return as_generator(
- "return Efl.Eo.Globals.cached_string_to_intptr(((" << name_helpers::klass_inherit_name(*klass) << ")wrapper).cached_strings, _ret_var);\n"
+ "return _ret_var;\n"
).generate(sink, attributes::unused, context);
}
else
@@ -1271,7 +1271,7 @@ struct native_convert_return_generator
return false;
}
return as_generator(
- "return Efl.Eo.Globals.cached_stringshare_to_intptr(((" << name_helpers::klass_inherit_name(*klass) << ")wrapper).cached_stringshares, _ret_var);\n"
+ "return _ret_var;\n"
).generate(sink, attributes::unused, context);
}
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
<< scope_tab << "{\n"
<< scope_tab << scope_tab << "get\n"
<< scope_tab << scope_tab << "{\n"
- << scope_tab << scope_tab << scope_tab << "Efl.Object obj = efl_part_get(NativeHandle, \"" << part.name << "\");\n"
+ << scope_tab << scope_tab << scope_tab << "Efl.Object obj = Efl.PartNativeInherit.efl_part_get_ptr.Value.Delegate(NativeHandle, \"" << part.name << "\");\n"
<< scope_tab << scope_tab << scope_tab << "return " << part_klass_name << ".static_cast(obj);\n"
<< scope_tab << scope_tab << "}\n"
<< 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
.generate(sink, nullptr, context))
return false;
}
+ else if (regular && !(regular->base_qualifier & efl::eolian::grammar::attributes::qualifier_info::is_ref)
+ && regular->base_type == "bool")
+ {
+ if (!as_generator("///<summary>Internal wrapper for field " << field_name << "</summary>\n"
+ "public System.Byte " << field_name << ";\n")
+ .generate(sink, nullptr, context))
+ return false;
+ }
+ else if (regular && !(regular->base_qualifier & efl::eolian::grammar::attributes::qualifier_info::is_ref)
+ && regular->base_type == "char")
+ {
+ if (!as_generator("///<summary>Internal wrapper for field " << field_name << "</summary>\n"
+ "public System.Byte " << field_name << ";\n")
+ .generate(sink, nullptr, context))
+ return false;
+ }
else if (!as_generator(scope_tab << eolian_mono::marshall_annotation(false) << "\n"
<< scope_tab << "public " << eolian_mono::marshall_type(false) << " " << string << ";\n")
.generate(sink, std::make_tuple(field.type, field.type, field_name), context))
@@ -255,6 +271,20 @@ struct to_internal_field_convert_generator
).generate(sink, std::make_tuple(field_name, field_name), context))
return false;
}
+ else if (!field.type.is_ptr && regular && regular->base_type == "bool")
+ {
+ if (!as_generator(
+ scope_tab << scope_tab << "_internal_struct." << string << " = _external_struct." << string << " ? (byte)1 : (byte)0;\n")
+ .generate(sink, std::make_tuple(field_name, field_name), context))
+ return false;
+ }
+ else if (!field.type.is_ptr && regular && regular->base_type == "char")
+ {
+ if (!as_generator(
+ scope_tab << scope_tab << "_internal_struct." << string << " = (byte)_external_struct." << string << ";\n")
+ .generate(sink, std::make_tuple(field_name, field_name), context))
+ return false;
+ }
else // primitives and enums
{
if (!as_generator(
@@ -358,6 +388,20 @@ struct to_external_field_convert_generator
).generate(sink, std::make_tuple(field_name, field_name), context))
return false;
}
+ else if (!field.type.is_ptr && regular && regular->base_type == "bool")
+ {
+ if (!as_generator(
+ scope_tab << scope_tab << "_external_struct." << string << " = _internal_struct." << string << " != 0;\n"
+ ).generate(sink, std::make_tuple(field_name, field_name), context))
+ return false;
+ }
+ else if (!field.type.is_ptr && regular && regular->base_type == "char")
+ {
+ if (!as_generator(
+ scope_tab << scope_tab << "_external_struct." << string << " = (char)_internal_struct." << string << ";\n"
+ ).generate(sink, std::make_tuple(field_name, field_name), context))
+ return false;
+ }
else // primitives and enums
{
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 @@
#include <utility>
#include <type_traits>
#include <tuple>
+#include <iosfwd>
#include <eina_aligned_union.hh>
@@ -149,6 +150,17 @@ struct destroy_visitor
}
};
+struct ostream_visitor
+{
+ std::ostream* s;
+ typedef std::ostream& result_type;
+ template <typename T>
+ std::ostream& operator()(T const& other) const
+ {
+ return *s << other;
+ }
+};
+
template <typename T>
struct get_visitor
{
@@ -295,6 +307,10 @@ private:
&& (rhs.type == -1
|| rhs.visit(compare_equal_visitor{&lhs.buffer}));
}
+ friend std::ostream& operator<<(std::ostream& s, variant<Args...> const& rhs)
+ {
+ return rhs.visit(ostream_visitor{&s});
+ }
int type;
/**
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;
namespace Efl {
static class UnsafeNativeMethods {
+
+ private delegate void init_func_delegate();
[DllImport(efl.Libs.Ecore)] public static extern void ecore_init();
[DllImport(efl.Libs.Ecore)] public static extern void ecore_shutdown();
- [DllImport(efl.Libs.Evas)] public static extern void evas_init();
+ // dotnet loads libraries from DllImport with RTLD_LOCAL. Due to the
+ // way evas modules are built with meson, currently they do not link directly
+ // with libevas, leading to symbol not found errors when trying to open them.
+ // The call to FunctionWrapper makes sure evas is loaded with RTLD_GLOBAL,
+ // allowing the symbols to remain visible for the modules until the build
+ // is sorted out.
+ private static Efl.Eo.FunctionWrapper<init_func_delegate> _evas_init;
[DllImport(efl.Libs.Evas)] public static extern void evas_shutdown();
[DllImport(efl.Libs.Elementary)] public static extern int elm_init(int argc, IntPtr argv);
[DllImport(efl.Libs.Elementary)] public static extern void elm_policy_set(int policy, int policy_detail);
[DllImport(efl.Libs.Elementary)] public static extern void elm_shutdown();
[DllImport(efl.Libs.Elementary)] public static extern void elm_run();
[DllImport(efl.Libs.Elementary)] public static extern void elm_exit();
+
+ static UnsafeNativeMethods() {
+ _evas_init = new Efl.Eo.FunctionWrapper<init_func_delegate>("evas", "evas_init");
+ }
+ public static void evas_init()
+ {
+ _evas_init.Value.Delegate();
+ }
}
public 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 {
public const string Eldbus = "@ELDBUS_DL_MONO@";
public const string CustomExports = "@CUSTOM_EXPORTS_MONO_DL_MONO@";
+
+ public const string Libdl = "libdl.so";
+ public const string Kernel32 = "kernel32.dll";
+
+ public static Efl.Eo.NativeModule EflModule = new Efl.Eo.NativeModule(Efl);
+ public static Efl.Eo.NativeModule CoreModule = new Efl.Eo.NativeModule(Ecore);
+ public static Efl.Eo.NativeModule EinaModule = new Efl.Eo.NativeModule(Eina);
+ public static Efl.Eo.NativeModule EoModule = new Efl.Eo.NativeModule(Eo);
+ public static Efl.Eo.NativeModule EvasModule = new Efl.Eo.NativeModule(Evas);
+ public static Efl.Eo.NativeModule EvilModule = new Efl.Eo.NativeModule(Evil);
+ public static Efl.Eo.NativeModule EdjeModule = new Efl.Eo.NativeModule(Edje);
+ public static Efl.Eo.NativeModule ElementaryModule = new Efl.Eo.NativeModule(Elementary);
+ public static Efl.Eo.NativeModule EldbusModule = new Efl.Eo.NativeModule(Eldbus);
+ public static Efl.Eo.NativeModule CustomExportsModule = new Efl.Eo.NativeModule(CustomExports);
+ public static Efl.Eo.NativeModule LibdlModule = new Efl.Eo.NativeModule(Libdl);
+ public static Efl.Eo.NativeModule Kernel32Module = new Efl.Eo.NativeModule(Kernel32);
}
}
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 {
}
}
-[StructLayout(LayoutKind.Sequential)]
-public struct ConvertWrapper<T>
-{
- public T val;
-}
-
public static class PrimitiveConversion
{
public static T PointerToManaged<T>(IntPtr nat)
@@ -111,8 +105,8 @@ public static class PrimitiveConversion
return default(T);
}
- var w = Marshal.PtrToStructure<Eina.ConvertWrapper<T> >(nat);
- return w.val;
+ var w = Marshal.PtrToStructure<T>(nat);
+ return w;
}
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;
using static Eina.InarrayNativeFunctions;
using static Eina.InlistNativeFunctions;
using static Eina.NativeCustomExportFunctions;
-using static Eina.ContainerCommonData;
namespace Eina {
public enum ElementType { NumericType, StringType, ObjectType };
-public static class ContainerCommonData
-{
- public static IBaseElementTraits<IntPtr> intPtrTraits = null;
-}
-
[StructLayout(LayoutKind.Sequential)]
public struct InlistMem
{
@@ -36,21 +30,17 @@ public struct InlistNode<T>
public T Val {get;set;}
}
-
public interface IBaseElementTraits<T>
{
IntPtr ManagedToNativeAlloc(T man);
- IntPtr ManagedToNativeAllocRef(T man, bool refs);
IntPtr ManagedToNativeAllocInlistNode(T man);
- IntPtr ManagedToNativeAllocInplace(T man);
+ void ManagedToNativeCopyTo(T man, IntPtr mem);
void NativeFree(IntPtr nat);
- void NativeFreeRef(IntPtr nat, bool unrefs);
void NativeFreeInlistNodeElement(IntPtr nat);
void NativeFreeInlistNode(IntPtr nat, bool freeElement);
void NativeFreeInplace(IntPtr nat);
void ResidueFreeInplace(IntPtr nat);
T NativeToManaged(IntPtr nat);
- T NativeToManagedRef(IntPtr nat);
T NativeToManagedInlistNode(IntPtr nat);
T NativeToManagedInplace(IntPtr nat);
IntPtr EinaCompareCb();
@@ -60,40 +50,33 @@ public interface IBaseElementTraits<T>
IntPtr EinaHashIteratorKeyNew(IntPtr hash);
}
-public class StringElementTraits<T> : IBaseElementTraits<T>
+public class StringElementTraits : IBaseElementTraits<string>
{
-
public StringElementTraits()
{
- if (intPtrTraits == null)
- intPtrTraits = TraitFunctions.GetTypeTraits<IntPtr>();
- }
-
- public IntPtr ManagedToNativeAlloc(T man)
- {
- return MemoryNative.StrDup((string)(object)man);
}
- public IntPtr ManagedToNativeAllocRef(T man, bool refs)
+ public IntPtr ManagedToNativeAlloc(string man)
{
- // Keep alloc on C# ?
- return ManagedToNativeAlloc(man);
+ IntPtr newstring = MemoryNative.StrDup(man);
+ return newstring;
}
- public IntPtr ManagedToNativeAllocInlistNode(T man)
+ public IntPtr ManagedToNativeAllocInlistNode(string man)
{
var node = new InlistNode<IntPtr>();
node.Val = ManagedToNativeAlloc(man);
GCHandle pinnedData = GCHandle.Alloc(node, GCHandleType.Pinned);
IntPtr ptr = pinnedData.AddrOfPinnedObject();
- IntPtr nat = MemoryNative.AllocCopy(ptr, Marshal.SizeOf<InlistNode<IntPtr> >());
+ IntPtr nat = MemoryNative.AllocCopy(ptr, Marshal.SizeOf<InlistMem>() + Marshal.SizeOf<IntPtr>());
pinnedData.Free();
return nat;
}
- public IntPtr ManagedToNativeAllocInplace(T man)
+ public void ManagedToNativeCopyTo(string man, IntPtr mem)
{
- return intPtrTraits.ManagedToNativeAlloc(ManagedToNativeAlloc(man));
+ IntPtr stringptr = ManagedToNativeAlloc(man);
+ Marshal.WriteIntPtr(mem, stringptr);
}
public void NativeFree(IntPtr nat)
@@ -102,17 +85,13 @@ public class StringElementTraits<T> : IBaseElementTraits<T>
MemoryNative.Free(nat);
}
- public void NativeFreeRef(IntPtr nat, bool unrefs)
- {
- NativeFree(nat);
- }
-
public void NativeFreeInlistNodeElement(IntPtr nat)
{
if (nat == IntPtr.Zero)
return;
- var node = Marshal.PtrToStructure< InlistNode<IntPtr> >(nat);
- NativeFree(node.Val);
+ var val = Marshal.PtrToStructure<IntPtr>
+ (nat + Marshal.SizeOf<InlistMem>());
+ NativeFree(val);
}
public void NativeFreeInlistNode(IntPtr nat, bool freeElement)
@@ -131,37 +110,35 @@ public class StringElementTraits<T> : IBaseElementTraits<T>
public void ResidueFreeInplace(IntPtr nat)
{
- intPtrTraits.NativeFree(nat);
}
- public T NativeToManaged(IntPtr nat)
+ public string NativeToManaged(IntPtr nat)
{
if (nat == IntPtr.Zero)
- return default(T);
- return (T)(object)StringConversion.NativeUtf8ToManagedString(nat);
+ return default(string);
+ return StringConversion.NativeUtf8ToManagedString(nat);
}
- public T NativeToManagedRef(IntPtr nat)
- {
- return NativeToManaged(nat);
- }
-
- public T NativeToManagedInlistNode(IntPtr nat)
+ public string NativeToManagedInlistNode(IntPtr nat)
{
if (nat == IntPtr.Zero)
{
Eina.Log.Error("Null pointer for Inlist node.");
- return default(T);
+ return default(string);
}
- var w = Marshal.PtrToStructure< InlistNode<IntPtr> >(nat);
- return NativeToManaged(w.Val);
+ IntPtr ptr_location = nat + Marshal.SizeOf<InlistMem>();
+ return NativeToManaged(Marshal.ReadIntPtr(ptr_location));
}
- public T NativeToManagedInplace(IntPtr nat)
+ // Strings inplaced are always a pointer, because they are variable-sized
+ public string NativeToManagedInplace(IntPtr nat)
{
if (nat == IntPtr.Zero)
- return default(T);
- return NativeToManaged(intPtrTraits.NativeToManaged(nat));
+ return default(string);
+ nat = Marshal.ReadIntPtr(nat);
+ if (nat == IntPtr.Zero)
+ return default(string);
+ return NativeToManaged(nat);
}
public IntPtr EinaCompareCb()
@@ -196,9 +173,6 @@ public class EflObjectElementTraits<T> : IBaseElementTraits<T>
public EflObjectElementTraits(System.Type concrete)
{
- if (intPtrTraits == null)
- intPtrTraits = TraitFunctions.GetTypeTraits<IntPtr>();
-
concreteType = concrete;
}
@@ -210,26 +184,21 @@ public class EflObjectElementTraits<T> : IBaseElementTraits<T>
return Efl.Eo.Globals.efl_ref(h);
}
- public IntPtr ManagedToNativeAllocRef(T man, bool refs)
- {
- IntPtr h = refs ? ManagedToNativeAlloc(man) : ((Efl.Eo.IWrapper)man).NativeHandle;
- return intPtrTraits.ManagedToNativeAlloc(h);
- }
-
public IntPtr ManagedToNativeAllocInlistNode(T man)
{
var node = new InlistNode<IntPtr>();
node.Val = ManagedToNativeAlloc(man);
GCHandle pinnedData = GCHandle.Alloc(node, GCHandleType.Pinned);
IntPtr ptr = pinnedData.AddrOfPinnedObject();
- IntPtr nat = MemoryNative.AllocCopy(ptr, Marshal.SizeOf<InlistNode<IntPtr> >());
+ IntPtr nat = MemoryNative.AllocCopy(ptr, Marshal.SizeOf<InlistMem>() + Marshal.SizeOf<IntPtr>());
pinnedData.Free();
return nat;
}
- public IntPtr ManagedToNativeAllocInplace(T man)
+ public void ManagedToNativeCopyTo(T man, IntPtr mem)
{
- return intPtrTraits.ManagedToNativeAlloc(ManagedToNativeAlloc(man));
+ IntPtr v = ManagedToNativeAlloc(man);
+ Marshal.WriteIntPtr(mem, v);
}
public void NativeFree(IntPtr nat)
@@ -241,16 +210,16 @@ public class EflObjectElementTraits<T> : IBaseElementTraits<T>
public void NativeFreeRef(IntPtr nat, bool unrefs)
{
if (unrefs)
- NativeFree(intPtrTraits.NativeToManaged(nat));
- intPtrTraits.NativeFree(nat);
+ NativeFree(nat);
}
public void NativeFreeInlistNodeElement(IntPtr nat)
{
if (nat == IntPtr.Zero)
return;
- var node = Marshal.PtrToStructure< InlistNode<IntPtr> >(nat);
- NativeFree(node.Val);
+ var val = Marshal.PtrToStructure<IntPtr>
+ (nat + Marshal.SizeOf<InlistMem>());
+ NativeFree(val);
}
public void NativeFreeInlistNode(IntPtr nat, bool freeElement)
@@ -264,12 +233,11 @@ public class EflObjectElementTraits<T> : IBaseElementTraits<T>
public void NativeFreeInplace(IntPtr nat)
{
- NativeFree(intPtrTraits.NativeToManaged(nat));
+ NativeFree(nat);
}
public void ResidueFreeInplace(IntPtr nat)
{
- intPtrTraits.NativeFree(nat);
}
public T NativeToManaged(IntPtr nat)
@@ -283,7 +251,7 @@ public class EflObjectElementTraits<T> : IBaseElementTraits<T>
{
if (nat == IntPtr.Zero)
return default(T);
- return NativeToManaged(intPtrTraits.NativeToManaged(nat));
+ return NativeToManaged(nat);
}
public T NativeToManagedInlistNode(IntPtr nat)
@@ -293,15 +261,19 @@ public class EflObjectElementTraits<T> : IBaseElementTraits<T>
Eina.Log.Error("Null pointer for Inlist node.");
return default(T);
}
- var w = Marshal.PtrToStructure< InlistNode<IntPtr> >(nat);
- return NativeToManaged(w.Val);
+ IntPtr ptr_location = nat + Marshal.SizeOf<InlistMem>();
+ return NativeToManaged(Marshal.ReadIntPtr(ptr_location));
}
+ // EFL objects inplaced are always a pointer, because they are variable-sized
public T NativeToManagedInplace(IntPtr nat)
{
if (nat == IntPtr.Zero)
return default(T);
- return NativeToManaged(intPtrTraits.NativeToManaged(nat));
+ nat = Marshal.ReadIntPtr(nat);
+ if (nat == IntPtr.Zero)
+ return default(T);
+ return NativeToManaged(nat);
}
public IntPtr EinaCompareCb()
@@ -345,16 +317,12 @@ public abstract class PrimitiveElementTraits<T>
node.Val = man;
GCHandle pinnedData = GCHandle.Alloc(node, GCHandleType.Pinned);
IntPtr ptr = pinnedData.AddrOfPinnedObject();
- IntPtr nat = MemoryNative.AllocCopy(ptr, Marshal.SizeOf< InlistNode<T> >());
+ int Tsize = Marshal.SizeOf<T>() < Marshal.SizeOf<IntPtr>() ? Marshal.SizeOf<IntPtr>() : Marshal.SizeOf<T>();
+ IntPtr nat = MemoryNative.AllocCopy(ptr, Marshal.SizeOf<InlistMem>() + Tsize);
pinnedData.Free();
return nat;
}
- public IntPtr ManagedToNativeAllocInplace(T man)
- {
- return ManagedToNativeAlloc(man);
- }
-
public void NativeFree(IntPtr nat)
{
MemoryNative.Free(nat);
@@ -395,16 +363,6 @@ public abstract class PrimitiveElementTraits<T>
return NativeToManaged(nat);
}
- public T NativeToManagedInlistNode(IntPtr nat)
- {
- if (nat == IntPtr.Zero)
- {
- Eina.Log.Error("Null pointer for Inlist node.");
- return default(T);
- }
- var w = Marshal.PtrToStructure< InlistNode<T> >(nat);
- return w.Val;
- }
public T NativeToManagedInplace(IntPtr nat)
{
@@ -441,7 +399,7 @@ public abstract class PrimitiveElementTraits<T>
}
}
-public class Primitive32ElementTraits<T> : PrimitiveElementTraits<T>, IBaseElementTraits<T>
+abstract public class Primitive32ElementTraits<T> : PrimitiveElementTraits<T>, IBaseElementTraits<T>
{
private static IBaseElementTraits<Int32> int32Traits = null;
@@ -454,6 +412,9 @@ public class Primitive32ElementTraits<T> : PrimitiveElementTraits<T>, IBaseEleme
int32Traits = TraitFunctions.GetTypeTraits<Int32>();
}
+ public abstract void ManagedToNativeCopyTo(T man, IntPtr mem);
+ public abstract T NativeToManagedInlistNode(IntPtr nat);
+
public IntPtr ManagedToNativeAllocRef(T man, bool refs)
{
return int32Traits.ManagedToNativeAlloc(Convert.ToInt32((object)man));
@@ -470,7 +431,7 @@ public class Primitive32ElementTraits<T> : PrimitiveElementTraits<T>, IBaseEleme
}
}
-public class Primitive64ElementTraits<T> : PrimitiveElementTraits<T>, IBaseElementTraits<T>
+abstract public class Primitive64ElementTraits<T> : PrimitiveElementTraits<T>, IBaseElementTraits<T>
{
private static IBaseElementTraits<Int64> int64Traits = null;
@@ -483,6 +444,9 @@ public class Primitive64ElementTraits<T> : PrimitiveElementTraits<T>, IBaseEleme
int64Traits = TraitFunctions.GetTypeTraits<Int64>();
}
+ public abstract void ManagedToNativeCopyTo(T man, IntPtr mem);
+ public abstract T NativeToManagedInlistNode(IntPtr nat);
+
public IntPtr ManagedToNativeAllocRef(T man, bool refs)
{
return int64Traits.ManagedToNativeAlloc(Convert.ToInt64((object)man));
@@ -499,6 +463,159 @@ public class Primitive64ElementTraits<T> : PrimitiveElementTraits<T>, IBaseEleme
}
}
+public class IntElementTraits : Primitive32ElementTraits<int>, IBaseElementTraits<int>
+{
+ override public void ManagedToNativeCopyTo(int man, IntPtr mem)
+ {
+ var arr = new int[1];
+ arr[0] = man;
+ Marshal.Copy(arr, 0, mem, 1);
+ }
+ override public int NativeToManagedInlistNode(IntPtr nat)
+ {
+ if (nat == IntPtr.Zero)
+ {
+ Eina.Log.Error("Null pointer for Inlist node.");
+ return default(int);
+ }
+ IntPtr loc = nat + Marshal.SizeOf<InlistMem>();
+ var v = new int[1];
+ Marshal.Copy(loc, v, 0, 1);
+ return v[0];
+ }
+}
+
+public class CharElementTraits : Primitive32ElementTraits<char>, IBaseElementTraits<char>
+{
+ override public void ManagedToNativeCopyTo(char man, IntPtr mem)
+ {
+ var arr = new char[1];
+ arr[0] = man;
+ Marshal.Copy(arr, 0, mem, 1);
+ }
+ override public char NativeToManagedInlistNode(IntPtr nat)
+ {
+ if (nat == IntPtr.Zero)
+ {
+ Eina.Log.Error("Null pointer for Inlist node.");
+ return default(char);
+ }
+ IntPtr loc = nat + Marshal.SizeOf<InlistMem>();
+ var v = new char[1];
+ Marshal.Copy(loc, v, 0, 1);
+ return v[0];
+ }
+}
+public class LongElementTraits : Primitive64ElementTraits<long>, IBaseElementTraits<long>
+{
+ override public void ManagedToNativeCopyTo(long man, IntPtr mem)
+ {
+ var arr = new long[1];
+ arr[0] = man;
+ Marshal.Copy(arr, 0, mem, 1);
+ }
+ override public long NativeToManagedInlistNode(IntPtr nat)
+ {
+ if (nat == IntPtr.Zero)
+ {
+ Eina.Log.Error("Null pointer for Inlist node.");
+ return default(long);
+ }
+ IntPtr loc = nat + Marshal.SizeOf<InlistMem>();
+ var v = new long[1];
+ Marshal.Copy(loc, v, 0, 1);
+ return v[0];
+ }
+}
+
+public class ShortElementTraits : Primitive32ElementTraits<short>, IBaseElementTraits<short>
+{
+ override public void ManagedToNativeCopyTo(short man, IntPtr mem)
+ {
+ var arr = new short[1];
+ arr[0] = man;
+ Marshal.Copy(arr, 0, mem, 1);
+ }
+ override public short NativeToManagedInlistNode(IntPtr nat)
+ {
+ if (nat == IntPtr.Zero)
+ {
+ Eina.Log.Error("Null pointer for Inlist node.");
+ return default(short);
+ }
+ IntPtr loc = nat + Marshal.SizeOf<InlistMem>();
+ var v = new short[1];
+ Marshal.Copy(loc, v, 0, 1);
+ return v[0];
+ }
+}
+
+public class FloatElementTraits : Primitive32ElementTraits<float>, IBaseElementTraits<float>
+{
+ override public void ManagedToNativeCopyTo(float man, IntPtr mem)
+ {
+ var arr = new float[1];
+ arr[0] = man;
+ Marshal.Copy(arr, 0, mem, 1);
+ }
+ override public float NativeToManagedInlistNode(IntPtr nat)
+ {
+ if (nat == IntPtr.Zero)
+ {
+ Eina.Log.Error("Null pointer for Inlist node.");
+ return default(float);
+ }
+ IntPtr loc = nat + Marshal.SizeOf<InlistMem>();
+ var v = new float[1];
+ Marshal.Copy(loc, v, 0, 1);
+ return v[0];
+ }
+}
+
+public class DoubleElementTraits : Primitive64ElementTraits<double>, IBaseElementTraits<double>
+{
+ override public void ManagedToNativeCopyTo(double man, IntPtr mem)
+ {
+ var arr = new double[1];
+ arr[0] = man;
+ Marshal.Copy(arr, 0, mem, 1);
+ }
+ override public double NativeToManagedInlistNode(IntPtr nat)
+ {
+ if (nat == IntPtr.Zero)
+ {
+ Eina.Log.Error("Null pointer for Inlist node.");
+ return default(double);
+ }
+ IntPtr loc = nat + Marshal.SizeOf<InlistMem>();
+ var v = new double[1];
+ Marshal.Copy(loc, v, 0, 1);
+ return v[0];
+ }
+}
+
+public class ByteElementTraits : Primitive32ElementTraits<byte>, IBaseElementTraits<byte>
+{
+ override public void ManagedToNativeCopyTo(byte man, IntPtr mem)
+ {
+ var arr = new byte[1];
+ arr[0] = man;
+ Marshal.Copy(arr, 0, mem, 1);
+ }
+ override public byte NativeToManagedInlistNode(IntPtr nat)
+ {
+ if (nat == IntPtr.Zero)
+ {
+ Eina.Log.Error("Null pointer for Inlist node.");
+ return default(byte);
+ }
+ IntPtr loc = nat + Marshal.SizeOf<InlistMem>();
+ var v = new byte[1];
+ Marshal.Copy(loc, v, 0, 1);
+ return v[0];
+ }
+}
+
public static class TraitFunctions
{
public static bool IsEflObject(System.Type type)
@@ -539,6 +656,7 @@ public static class TraitFunctions
public static object RegisterTypeTraits<T>()
{
+ Eina.Log.Debug($"Finding TypeTraits for {typeof(T).Name}");
object traits;
var type = typeof(T);
if (IsEflObject(type))
@@ -549,13 +667,25 @@ public static class TraitFunctions
traits = new EflObjectElementTraits<T>(concrete);
}
else if (IsString(type))
- traits = new StringElementTraits<T>();
+ traits = new StringElementTraits();
else if (type.IsValueType)
{
- if (Marshal.SizeOf<T>() <= 4)
- traits = new Primitive32ElementTraits<T>();
+ if (type == typeof(int))
+ traits = new IntElementTraits();
+ else if (type == typeof(char))
+ traits = new CharElementTraits();
+ else if (type == typeof(long))
+ traits = new LongElementTraits();
+ else if (type == typeof(short))
+ traits = new ShortElementTraits();
+ else if (type == typeof(float))
+ traits = new FloatElementTraits();
+ else if (type == typeof(double))
+ traits = new DoubleElementTraits();
+ else if (type == typeof(byte))
+ traits = new ByteElementTraits();
else
- traits = new Primitive64ElementTraits<T>();
+ throw new Exception("No traits registered for this type");
}
else
throw new Exception("No traits registered for this type");
@@ -589,14 +719,9 @@ public static class TraitFunctions
return GetTypeTraits<T>().ManagedToNativeAlloc(man);
}
- public static IntPtr ManagedToNativeAllocRef<T>(T man, bool refs = false)
+ public static void ManagedToNativeCopyTo<T>(T man, IntPtr mem)
{
- return GetTypeTraits<T>().ManagedToNativeAllocRef(man, refs);
- }
-
- public static IntPtr ManagedToNativeAllocInplace<T>(T man)
- {
- return GetTypeTraits<T>().ManagedToNativeAllocInplace(man);
+ GetTypeTraits<T>().ManagedToNativeCopyTo(man, mem);
}
public static IntPtr ManagedToNativeAllocInlistNode<T>(T man)
@@ -609,11 +734,6 @@ public static class TraitFunctions
GetTypeTraits<T>().NativeFree(nat);
}
- public static void NativeFreeRef<T>(IntPtr nat, bool unrefs = false)
- {
- GetTypeTraits<T>().NativeFreeRef(nat, unrefs);
- }
-
public static void NativeFreeInlistNodeElement<T>(IntPtr nat)
{
GetTypeTraits<T>().NativeFreeInlistNodeElement(nat);
@@ -639,11 +759,6 @@ public static class TraitFunctions
return GetTypeTraits<T>().NativeToManaged(nat);
}
- public static T NativeToManagedRef<T>(IntPtr nat)
- {
- return GetTypeTraits<T>().NativeToManagedRef(nat);
- }
-
public static T NativeToManagedInlistNode<T>(IntPtr nat)
{
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
public bool AddNew(TKey key, TValue val)
{
- var nk = ManagedToNativeAllocRef(key, true);
- var nv = ManagedToNativeAlloc(val);
+ IntPtr gchnk = CopyNativeObject(key, ForceRefKey<TKey>());
+ IntPtr nk = GetNativePtr<TKey>(gchnk, ForceRefKey<TKey>());
+ IntPtr gchnv = CopyNativeObject(val, false);
+ IntPtr nv = GetNativePtr<TValue>(gchnv, false);
var r = eina_hash_add(Handle, nk, nv);
- NativeFreeRef<TKey>(nk);
+ FreeNativeIndirection<TKey>(gchnk, ForceRefKey<TKey>());
+ FreeNativeIndirection<TValue>(gchnv, false);
return r;
}
@@ -256,17 +259,20 @@ public class Hash<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>, IDi
public bool DelByKey(TKey key)
{
- var nk = ManagedToNativeAllocRef(key);
+ IntPtr gchnk = CopyNativeObject(key, ForceRefKey<TKey>());
+ IntPtr nk = GetNativePtr<TKey>(gchnk, ForceRefKey<TKey>());
var r = eina_hash_del_by_key(Handle, nk);
- NativeFreeRef<TKey>(nk, OwnKey && r);
+ FreeNativeIndirection<TKey>(gchnk, ForceRefKey<TKey>());
+ // NativeFreeRef<TKey>(nk, OwnKey && r);
return r;
}
public bool DelByValue(TValue val)
{
- var nv = ManagedToNativeAlloc(val);
+ IntPtr gchnv = CopyNativeObject(val, false);
+ IntPtr nv = GetNativePtr<TValue>(gchnv, false);
var r = eina_hash_del_by_data(Handle, nv);
- NativeFree<TValue>(nv);
+ FreeNativeIndirection<TValue>(gchnv, false);
return r;
}
@@ -277,42 +283,52 @@ public class Hash<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>, IDi
public TValue Find(TKey key)
{
- var nk = ManagedToNativeAllocRef(key);
+ var gchnk = CopyNativeObject<TKey>(key, ForceRefKey<TKey>());
+ var nk = GetNativePtr<TKey>(gchnk, ForceRefKey<TKey>());
var found = eina_hash_find(Handle, nk);
- NativeFreeRef<TKey>(nk);
+ //NativeFreeRef<TKey>(nk);
+ FreeNativeIndirection<TKey>(gchnk, ForceRefKey<TKey>());
if (found == IntPtr.Zero)
throw new KeyNotFoundException();
- return NativeToManaged<TValue>(found);
+
+ return NativeToManaged<TValue>(IndirectNative<TValue>(found, false));
}
public bool TryGetValue(TKey key, out TValue val)
{
- var nk = ManagedToNativeAllocRef(key);
+ var gchnk = CopyNativeObject<TKey>(key, ForceRefKey<TKey>());
+ var nk = GetNativePtr<TKey>(gchnk, ForceRefKey<TKey>());
var found = eina_hash_find(Handle, nk);
- NativeFreeRef<TKey>(nk);
+ FreeNativeIndirection<TKey>(gchnk, ForceRefKey<TKey>());
if (found == IntPtr.Zero)
{
val = default(TValue);
return false;
}
- val = NativeToManaged<TValue>(found);
+ val = NativeToManaged<TValue>(IndirectNative<TValue>(found, false));
return true;
}
public bool ContainsKey(TKey key)
{
- var nk = ManagedToNativeAllocRef(key);
+ var gchnk = CopyNativeObject<TKey>(key, ForceRefKey<TKey>());
+ var nk = GetNativePtr<TKey>(gchnk, ForceRefKey<TKey>());
+ // var nk = ManagedToNativeAllocRef(key);
var found = eina_hash_find(Handle, nk);
- NativeFreeRef<TKey>(nk);
+ // NativeFreeRef<TKey>(nk);
+ FreeNativeIndirection<TKey>(gchnk, ForceRefKey<TKey>());
return found != IntPtr.Zero;
}
public bool Modify(TKey key, TValue val)
{
- var nk = ManagedToNativeAllocRef(key);
- var nv = ManagedToNativeAlloc(val);
+ var gchnk = CopyNativeObject<TKey>(key, ForceRefKey<TKey>());
+ var nk = GetNativePtr<TKey>(gchnk, ForceRefKey<TKey>());
+ var gchnv = CopyNativeObject<TValue>(val, false);
+ var nv = GetNativePtr<TValue>(gchnv, false);
var old = eina_hash_modify(Handle, nk, nv);
- NativeFreeRef<TKey>(nk);
+ FreeNativeIndirection<TKey>(gchnk, ForceRefKey<TKey>());
+ // NativeFreeRef<TKey>(nk);
if (old == IntPtr.Zero)
{
NativeFree<TValue>(nv);
@@ -323,14 +339,82 @@ public class Hash<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>, IDi
return true;
}
+ private static bool ForceRefKey<T>()
+ {
+ return (!typeof(T).IsValueType) && (typeof(T) != typeof(string));
+ }
+
+ private static IntPtr CopyNativeObject<T>(T value, bool forceRef)
+ {
+ if (!IsEflObject(typeof(T)) && forceRef)
+ {
+ GCHandle gch = GCHandle.Alloc(new byte[Marshal.SizeOf<T>()], GCHandleType.Pinned);
+ IntPtr pin = gch.AddrOfPinnedObject();
+
+ ManagedToNativeCopyTo(value, pin);
+
+ return GCHandle.ToIntPtr(gch);
+ }
+ else if(IsEflObject(typeof(T)) && forceRef)
+ {
+ GCHandle gch = GCHandle.Alloc(new byte[Marshal.SizeOf<IntPtr>()], GCHandleType.Pinned);
+ IntPtr pin = gch.AddrOfPinnedObject();
+
+ ManagedToNativeCopyTo(value, pin);
+
+ return GCHandle.ToIntPtr(gch);
+ }
+ else
+ {
+ return ManagedToNativeAlloc(value);
+ }
+ }
+ private static IntPtr GetNativePtr<T>(IntPtr gchptr, bool forceRef)
+ {
+ if (forceRef)
+ {
+ GCHandle gch = GCHandle.FromIntPtr(gchptr);
+ IntPtr pin = gch.AddrOfPinnedObject();
+
+ return pin;
+ }
+ else
+ {
+ return gchptr;
+ }
+ }
+ private static void FreeNativeIndirection<T>(IntPtr gchptr, bool forceRef)
+ {
+ if (forceRef)
+ {
+ GCHandle gch = GCHandle.FromIntPtr(gchptr);
+ gch.Free();
+ }
+ }
+
+ private static IntPtr IndirectNative<T>(IntPtr ptr, bool forceRef)
+ {
+ if (forceRef)
+ {
+ IntPtr val = Marshal.ReadIntPtr(ptr);
+ return val;
+ }
+ else
+ {
+ return ptr;
+ }
+ }
+
public void Set(TKey key, TValue val)
{
- var nk = ManagedToNativeAllocRef(key, true);
- var nv = ManagedToNativeAlloc(val);
- var old = eina_hash_set(Handle, nk, nv);
- NativeFreeRef<TKey>(nk, old != IntPtr.Zero);
- if (old != IntPtr.Zero && OwnValue)
- NativeFree<TValue>(old);
+ IntPtr gchnk = CopyNativeObject(key, ForceRefKey<TKey>());
+ IntPtr nk = GetNativePtr<TKey>(gchnk, ForceRefKey<TKey>());
+
+ IntPtr gchnv = CopyNativeObject(val, false);
+ IntPtr nv = GetNativePtr<TValue>(gchnv, false);
+ IntPtr old = eina_hash_set(Handle, nk, nv);
+ FreeNativeIndirection<TKey>(gchnk, ForceRefKey<TKey>());
+ FreeNativeIndirection<TValue>(gchnv, false);
}
public TValue this[TKey key]
@@ -347,11 +431,17 @@ public class Hash<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>, IDi
public bool Move(TKey key_old, TKey key_new)
{
- var nk_old = ManagedToNativeAllocRef(key_old);
- var nk_new = ManagedToNativeAllocRef(key_new, true);
- var r = eina_hash_move(Handle, nk_old, nk_new);
- NativeFreeRef<TKey>(nk_old, OwnKey && r);
- NativeFreeRef<TKey>(nk_new, !r);
+ IntPtr gchnko = CopyNativeObject(key_old, ForceRefKey<TKey>());
+ IntPtr nko = GetNativePtr<TKey>(gchnko, ForceRefKey<TKey>());
+ IntPtr gchnk = CopyNativeObject(key_new, ForceRefKey<TKey>());
+ IntPtr nk = GetNativePtr<TKey>(gchnk, ForceRefKey<TKey>());
+ // var nk_old = ManagedToNativeAllocRef(key_old);
+ // var nk_new = ManagedToNativeAllocRef(key_new, true);
+ var r = eina_hash_move(Handle, nko, nk);
+ FreeNativeIndirection<TKey>(gchnko, ForceRefKey<TKey>());
+ FreeNativeIndirection<TKey>(gchnk, ForceRefKey<TKey>());
+ // NativeFreeRef<TKey>(nk_old, OwnKey && r);
+ // NativeFreeRef<TKey>(nk_new, !r);
return r;
}
@@ -383,7 +473,8 @@ public class Hash<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>, IDi
for (IntPtr tuplePtr; eina_iterator_next(itr, out tuplePtr);)
{
var tuple = Marshal.PtrToStructure<Eina.HashTupleNative>(tuplePtr);
- var key = NativeToManagedRef<TKey>(tuple.key);
+ IntPtr ikey = IndirectNative<TKey>(tuple.key, ForceRefKey<TKey>());
+ var key = NativeToManaged<TKey>(ikey);
var val = NativeToManaged<TValue>(tuple.data);
yield return new KeyValuePair<TKey, TValue>(key, val);
}
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
public int Push(T val)
{
- IntPtr ele = ManagedToNativeAllocInplace(val);
- var r = eina_inarray_push(Handle, ele);
+ IntPtr ele = IntPtr.Zero;
+ GCHandle gch = GCHandle.Alloc(ele, GCHandleType.Pinned);
+ IntPtr ind = gch.AddrOfPinnedObject();
+
+ ManagedToNativeCopyTo(val, ind);
+
+ var r = eina_inarray_push(Handle, ind);
if (r == -1)
NativeFreeInplace<T>(ele);
ResidueFreeInplace<T>(ele);
+ gch.Free();
return r;
}
@@ -220,6 +226,7 @@ public class Inarray<T> : IEnumerable<T>, IDisposable
public T Nth(uint idx)
{
IntPtr ele = eina_inarray_nth(Handle, idx);
+ IntPtr v = Marshal.ReadIntPtr(ele);
return NativeToManagedInplace<T>(ele);
}
@@ -230,8 +237,13 @@ public class Inarray<T> : IEnumerable<T>, IDisposable
public bool InsertAt(uint idx, T val)
{
- IntPtr ele = ManagedToNativeAllocInplace(val);
- var r = eina_inarray_insert_at(Handle, idx, ele);
+ IntPtr ele = IntPtr.Zero;
+ GCHandle gch = GCHandle.Alloc(ele, GCHandleType.Pinned);
+ IntPtr ind = gch.AddrOfPinnedObject();
+
+ ManagedToNativeCopyTo(val, ind);
+
+ var r = eina_inarray_insert_at(Handle, idx, ind);
if (!r)
NativeFreeInplace<T>(ele);
ResidueFreeInplace<T>(ele);
@@ -245,8 +257,13 @@ public class Inarray<T> : IEnumerable<T>, IDisposable
return false;
if (OwnContent)
NativeFreeInplace<T>(old);
- var ele = ManagedToNativeAllocInplace(val);
- var r = eina_inarray_replace_at(Handle, idx, ele);
+ var ele = IntPtr.Zero;
+ GCHandle gch = GCHandle.Alloc(ele, GCHandleType.Pinned);
+ IntPtr ind = gch.AddrOfPinnedObject();
+
+ ManagedToNativeCopyTo(val, ind);
+
+ var r = eina_inarray_replace_at(Handle, idx, ind);
ResidueFreeInplace<T>(ele);
return r;
}
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 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace Efl { namespace Eo {
+
+public partial class FunctionInterop
+{
+ public static IntPtr LoadFunctionPointer(string moduleName, string functionName)
+ {
+ NativeModule module = new NativeModule(moduleName);
+ Eina.Log.Debug($"searching {module.Module} for {functionName}");
+ var s = FunctionInterop.dlsym(module.Module, functionName);
+ Eina.Log.Debug($"searching {module.Module} for{functionName}, result {s}");
+ return s;
+ }
+ public static IntPtr LoadFunctionPointer(string functionName)
+ {
+ Eina.Log.Debug($"searching {null} for {functionName}");
+ var s = FunctionInterop.dlsym(IntPtr.Zero, functionName);
+ Eina.Log.Debug($"searching {null} for {functionName}, result {s}");
+ return s;
+ }
+}
+
+public class FunctionWrapper<T>
+{
+ private Lazy<FunctionLoadResult<T>> loadResult;
+ private NativeModule module; // so it doesn't get unloaded
+
+ private static FunctionLoadResult<T> LazyInitialization(NativeModule module, string functionName)
+ {
+ if (module.Module == IntPtr.Zero)
+ return new FunctionLoadResult<T>(FunctionLoadResultKind.LibraryNotFound);
+ else
+ {
+ IntPtr funcptr = FunctionInterop.LoadFunctionPointer(module.Module, functionName);
+ if (funcptr == IntPtr.Zero)
+ return new FunctionLoadResult<T>(FunctionLoadResultKind.FunctionNotFound);
+ else
+ return new FunctionLoadResult<T>(Marshal.GetDelegateForFunctionPointer<T>(funcptr));
+ }
+ }
+
+ public FunctionWrapper(string moduleName, string functionName)
+ : this (new NativeModule(moduleName), functionName)
+ {
+ }
+
+ public FunctionWrapper(NativeModule module, string functionName)
+ {
+ this.module = module;
+ loadResult = new Lazy<FunctionLoadResult<T>>
+ (() =>
+ {
+ return LazyInitialization(module, functionName);
+ });
+ }
+
+ public FunctionLoadResult<T> Value
+ {
+ get
+ {
+ return loadResult.Value;
+ }
+ }
+}
+
+public enum FunctionLoadResultKind { Success, LibraryNotFound, FunctionNotFound }
+
+public class FunctionLoadResult<T>
+{
+ public FunctionLoadResultKind Kind;
+ public T _Delegate;
+ public T Delegate
+ {
+ get {
+ if (_Delegate == null)
+ throw new InvalidOperationException($"Trying to get Delegate while not loaded. Load result: {Kind}");
+ return _Delegate;
+ }
+ }
+
+ public FunctionLoadResult(FunctionLoadResultKind kind)
+ {
+ this.Kind = kind;
+ }
+ public FunctionLoadResult(T Delegate)
+ {
+ this._Delegate = Delegate;
+ this.Kind = FunctionLoadResultKind.Success;
+ }
+}
+
+
+} }
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 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace Efl { namespace Eo {
+
+public partial class FunctionInterop
+{
+ [DllImport(efl.Libs.Libdl)]
+ public static extern IntPtr dlsym(IntPtr handle, string symbol);
+
+ public static IntPtr LoadFunctionPointer(IntPtr nativeLibraryHandle, string functionName)
+ {
+ Eina.Log.Debug("searching {nativeLibraryHandle} for {functionName}");
+ var s = FunctionInterop.dlsym(nativeLibraryHandle, functionName);
+ Eina.Log.Debug("searching {nativeLibraryHandle} for {functionName}, result {s}");
+ return s;
+ }
+}
+
+
+} }
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 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace Efl { namespace Eo {
+
+public partial class FunctionInterop
+{
+ [DllImport(efl.Libs.Libdl)]
+ public static extern IntPtr GetProcAddress(IntPtr handle, string symbol);
+
+ private static IntPtr LoadFunctionPointer(IntPtr nativeLibraryHandle, string functionName)
+ => FunctionInterop.GetProcAddress(nativeLibraryHandle, functionName);
+}
+
+} }
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 @@
+using System;
+
+namespace Efl { namespace Eo {
+
+public partial class NativeModule : IDisposable
+{
+ private Lazy<IntPtr> module;
+
+ public NativeModule(string libName)
+ {
+ module = new Lazy<IntPtr>
+ (() =>
+ {
+ return LoadLibrary(libName);
+ });
+ }
+
+ public IntPtr Module
+ {
+ get
+ {
+ return module.Value;
+ }
+ }
+
+ public void Dispose()
+ {
+ UnloadLibrary(module.Value);
+ module = null;
+ }
+}
+
+} }
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 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace Efl { namespace Eo {
+
+public partial class NativeModule
+{
+ public const int RTLD_NOW = 0x002;
+ // Currently we are using GLOBAL due to issues
+ // with the way evas modules are built.
+ public const int RTLD_GLOBAL = 0x100;
+
+ [DllImport(efl.Libs.Libdl)]
+ public static extern IntPtr dlopen(string fileName, int flag);
+ [DllImport(efl.Libs.Libdl)]
+ public static extern int dlclose(IntPtr handle);
+
+ public static void UnloadLibrary(IntPtr handle)
+ {
+ dlclose(handle);
+ }
+
+ public static IntPtr LoadLibrary(string filename)
+ {
+ Eina.Log.Debug($"Loading library {filename}");
+ var r = dlopen(filename, RTLD_NOW | RTLD_GLOBAL);
+ if (r == IntPtr.Zero)
+ {
+ r = dlopen("lib" + filename, RTLD_NOW | RTLD_GLOBAL);
+ if (r == IntPtr.Zero)
+ {
+ r = dlopen(filename + ".so", RTLD_NOW | RTLD_GLOBAL);
+ if (r == IntPtr.Zero)
+ {
+ r = dlopen("lib" + filename + ".so", RTLD_NOW | RTLD_GLOBAL);
+ }
+ }
+ }
+ return r;
+ }
+}
+
+
+
+
+} }
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 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace Efl { namespace Eo {
+
+public class partial NativeModule
+{
+ [DllImport(efl.Libs.Kernel32, CharSet = CharSet.Unicode, SetLastError = true)]
+ public static extern IntPtr LoadLibrary(string libFilename);
+}
+
+
+
+
+} }
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;
namespace Efl { namespace Eo {
public class Globals {
- [DllImport(efl.Libs.Eo)] public static extern void efl_object_init();
- [DllImport(efl.Libs.Eo)] public static extern void efl_object_shutdown();
+ [return: MarshalAs(UnmanagedType.U1)]
+ public delegate bool efl_object_init_delegate();
+ public static FunctionWrapper<efl_object_init_delegate> efl_object_init_ptr =
+ new FunctionWrapper<efl_object_init_delegate>(efl.Libs.EoModule, "efl_object_init");
+ public static bool efl_object_init() => efl_object_init_ptr.Value.Delegate();
+
+ public delegate void efl_object_shutdown_delegate();
+ public static FunctionWrapper<efl_object_shutdown_delegate> efl_object_shutdown_ptr = new FunctionWrapper<efl_object_shutdown_delegate>(efl.Libs.EoModule, "efl_object_shutdown");
+ public static void efl_object_shutdown() => efl_object_shutdown_ptr.Value.Delegate();
+ // [DllImport(efl.Libs.Eo)] public static extern void efl_object_shutdown();
+ 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");
+ public delegate IntPtr
+ _efl_add_internal_start_delegate([MarshalAs(UnmanagedType.LPStr)] String file, int line,
+ IntPtr klass, IntPtr parent, byte is_ref, byte is_fallback);
[DllImport(efl.Libs.Eo)] public static extern IntPtr
_efl_add_internal_start([MarshalAs(UnmanagedType.LPStr)] String file, int line,
IntPtr klass, IntPtr parent, byte is_ref, byte is_fallback);
+ public delegate IntPtr
+ _efl_add_end_delegate(IntPtr eo, byte is_ref, byte is_fallback);
[DllImport(efl.Libs.Eo)] public static extern IntPtr
_efl_add_end(IntPtr eo, byte is_ref, byte is_fallback);
+ public delegate IntPtr
+ efl_ref_delegate(IntPtr eo);
[DllImport(efl.Libs.Eo)] public static extern IntPtr
efl_ref(IntPtr eo);
+ public delegate void
+ efl_unref_delegate(IntPtr eo);
[DllImport(efl.Libs.CustomExports)] public static extern void
efl_unref(IntPtr eo);
+ public delegate int
+ efl_ref_count_delegate(IntPtr eo);
[DllImport(efl.Libs.Eo)] public static extern int
efl_ref_count(IntPtr eo);
+
[DllImport(efl.Libs.Eo)] public static extern IntPtr
efl_class_name_get(IntPtr eo);
[DllImport(efl.Libs.Eo)] public static extern IntPtr
@@ -125,30 +146,42 @@ public class Globals {
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);
[DllImport(efl.Libs.Eo)] public static extern IntPtr
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);
- [DllImport(efl.Libs.Eo)] public static extern byte efl_class_functions_set(IntPtr klass_id, IntPtr object_ops, IntPtr class_ops, IntPtr reflection_ops);
+
+ public delegate byte efl_class_functions_set_delegate(IntPtr klass_id, IntPtr object_ops, IntPtr class_ops);
+ [DllImport(efl.Libs.Eo)] public static extern byte efl_class_functions_set(IntPtr klass_id, IntPtr object_ops, IntPtr class_ops);
+ public delegate IntPtr efl_data_scope_get_delegate(IntPtr obj, IntPtr klass);
[DllImport(efl.Libs.Eo)] public static extern IntPtr efl_data_scope_get(IntPtr obj, IntPtr klass);
+ public delegate IntPtr efl_super_delegate(IntPtr obj, IntPtr klass);
[DllImport(efl.Libs.Eo)] public static extern IntPtr efl_super(IntPtr obj, IntPtr klass);
+ public delegate IntPtr efl_class_get_delegate(IntPtr obj);
[DllImport(efl.Libs.Eo)] public static extern IntPtr efl_class_get(IntPtr obj);
-#if WIN32
- public static IntPtr RTLD_DEFAULT = new IntPtr(1);
-#else
- public static IntPtr RTLD_DEFAULT = new IntPtr(0);
-#endif
+ public delegate IntPtr dlerror_delegate();
[DllImport(efl.Libs.Evil)] public static extern IntPtr dlerror();
- [DllImport(efl.Libs.Evil)] public static extern IntPtr dlsym
- (IntPtr handle, [MarshalAs(UnmanagedType.LPStr)] String name);
- [DllImport(efl.Libs.Eo)] public static extern bool efl_event_callback_priority_add(
+ public delegate bool efl_event_callback_priority_add_delegate(
+ System.IntPtr obj,
+ IntPtr desc,
+ short priority,
+ Efl.EventCb cb,
+ System.IntPtr data);
+ [DllImport(efl.Libs.Eo)] public static extern bool efl_event_callback_priority_add(
System.IntPtr obj,
IntPtr desc,
short priority,
Efl.EventCb cb,
System.IntPtr data);
- [DllImport(efl.Libs.Eo)] public static extern bool efl_event_callback_del(
+ public delegate bool efl_event_callback_del_delegate(
System.IntPtr obj,
IntPtr desc,
Efl.EventCb cb,
System.IntPtr data);
+ [DllImport(efl.Libs.Eo)] public static extern bool efl_event_callback_del(
+ System.IntPtr obj,
+ IntPtr desc,
+ Efl.EventCb cb,
+ System.IntPtr data);
+ public delegate IntPtr
+ efl_object_legacy_only_event_description_get_delegate([MarshalAs(UnmanagedType.LPStr)] String name);
[DllImport(efl.Libs.Eo)] public static extern IntPtr
efl_object_legacy_only_event_description_get([MarshalAs(UnmanagedType.LPStr)] String name);
@@ -240,7 +273,7 @@ public class Globals {
}
public static byte class_initializer_call(IntPtr klass, System.Type type)
{
- Eina.Log.Debug($"called with 0x{klass.ToInt64()} {type}");
+ Eina.Log.Debug($"called with 0x{klass.ToInt64():x} {type}");
Efl.Eo.NativeClass nativeClass = get_native_class(type.BaseType);
if (nativeClass != null)
@@ -259,7 +292,7 @@ public class Globals {
if(nc != null)
{
var moredescs = nc.GetEoOps(type);
- Eina.Log.Debug("adding {moredescs.Count} more descs to registration");
+ Eina.Log.Debug($"adding {moredescs.Count} more descs to registration");
descs.AddRange(moredescs);
count = descs.Count;
}
@@ -278,7 +311,7 @@ public class Globals {
ops.count = (UIntPtr)count;
IntPtr ops_ptr = Marshal.AllocHGlobal(Marshal.SizeOf(ops));
Marshal.StructureToPtr(ops, ops_ptr, false);
- Efl.Eo.Globals.efl_class_functions_set(klass, ops_ptr, IntPtr.Zero, IntPtr.Zero);
+ Efl.Eo.Globals.efl_class_functions_set(klass, ops_ptr, IntPtr.Zero);
//EoKlass = klass;
}
else
@@ -391,38 +424,6 @@ public class Globals {
return null;
}
- public static IntPtr cached_string_to_intptr(Dictionary<String, IntPtr> dict, String str)
- {
- IntPtr ptr = IntPtr.Zero;
-
- if (str == null)
- return ptr;
-
- if (!dict.TryGetValue(str, out ptr))
- {
- ptr = Eina.StringConversion.ManagedStringToNativeUtf8Alloc(str);
- dict[str] = ptr;
- }
-
- return ptr;
- }
-
- public static IntPtr cached_stringshare_to_intptr(Dictionary<String, IntPtr> dict, String str)
- {
- IntPtr ptr = IntPtr.Zero;
-
- if (str == null)
- return ptr;
-
- if (!dict.TryGetValue(str, out ptr))
- {
- ptr = Eina.Stringshare.eina_stringshare_add(str);
- dict[str] = ptr;
- }
-
- return ptr;
- }
-
public static void free_dict_values(Dictionary<String, IntPtr> dict)
{
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 @@
mono_files += files(
'iwrapper.cs',
- 'workaround.cs'
+ 'workaround.cs',
+ 'FunctionWrapper.cs',
+ 'NativeModule.cs'
)
+
+if host_machine.system() == 'windows'
+ mono_files += files('FunctionWrapper_Windows.cs', 'NativeModule_Windows.cs')
+else
+ mono_files += files('FunctionWrapper_Unix.cs', 'NativeModule_Unix.cs')
+endif
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 {
private static Dictionary<string, IntPtr> descriptions = new Dictionary<string, IntPtr>();
- public EventDescription(string name)
+ public EventDescription(string module, string name)
{
- this.Name = GetNative(name);
+ this.Name = GetNative(module, name);
this.Unfreezable = false;
this.Legacy_is = false;
this.Restart = false;
}
- public static IntPtr GetNative(string name)
+ public static IntPtr GetNative(string module, string name)
{
if (!descriptions.ContainsKey(name))
{
- IntPtr data = Efl.Eo.Globals.dlsym(Efl.Eo.Globals.RTLD_DEFAULT, name);
+ IntPtr data = Efl.Eo.FunctionInterop.LoadFunctionPointer(module, name);
if (data == IntPtr.Zero) {
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 @@
add_languages('cs')
+
+runtime_assemblies = []
+
+# Check if we should use dotnet options
+cs_is_dotnet = meson.get_compiler('cs').get_id().contains('dotnet')
+
+if (cs_is_dotnet)
+
+runtime_assemblies += [
+ 'System.Console',
+ 'Microsoft.CSharp',
+ 'System.Collections',
+ 'System.Collections.Concurrent',
+ 'System.ComponentModel.Primitives',
+ 'System.ComponentModel.Primitives',
+ 'System.Diagnostics.Debug',
+ 'System.Diagnostics.TraceSource',
+ 'System.Dynamic.Runtime',
+ 'System.Linq',
+ 'System.Runtime',
+ 'System.Runtime.Extensions',
+ 'System.Security',
+]
+
+endif
+
mono_sublibs = [
['Eina', true, ], #
['Eolian', true, ], #
@@ -114,15 +140,24 @@ efl_mono_conf_data.set('EVAS', evas_lib.full_path())
efl_mono_conf_data.set('ELDBUS', eldbus_lib.full_path())
efl_mono_conf_data.set('ELEMENTARY', elementary_lib.full_path())
-configure_file(input : 'efl_mono.dll.config.in',
- output : 'efl_mono.dll.config',
- configuration : efl_mono_conf_data)
+efl_mono_dll_config = configure_file(input : 'efl_mono.dll.config.in',
+ output : 'efl_mono.dll.config',
+ configuration : efl_mono_conf_data)
+if (cs_is_dotnet)
+efl_mono = library('efl_mono',
+ mono_generator_target + mono_files + [efl_src],
+ install : true,
+ install_dir : join_paths(dir_lib, 'efl-mono-'+version_major),
+ runtime_assemblies : runtime_assemblies
+)
+else
efl_mono = library('efl_mono',
mono_generator_target + mono_files + [efl_src],
install : true,
- install_dir : join_paths(dir_lib, 'efl-mono-'+version_major)
+ install_dir : join_paths(dir_lib, 'efl-mono-'+version_major),
)
+endif
efl_mono_test_suite_path=join_paths(meson.current_build_dir())
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 @@
#include <vector>
#include <memory>
#include <set>
+#include <iosfwd>
+#include <string>
namespace efl { namespace eolian { namespace grammar {
@@ -73,6 +75,26 @@ enum class typedecl_type
function_ptr,
};
+inline std::ostream& operator<<(std::ostream& s, typedecl_type dec)
+{
+ switch(dec)
+ {
+ case typedecl_type::unknown:
+ return s << "unknown";
+ case typedecl_type::struct_:
+ return s << "struct_";
+ case typedecl_type::struct_opaque:
+ return s << "struct_opaque";
+ case typedecl_type::enum_:
+ return s << "enum_";
+ case typedecl_type::alias:
+ return s << "alias";
+ case typedecl_type::function_ptr:
+ return s << "function_ptr";
+ };
+ return s;
+}
+
inline typedecl_type typedecl_type_get(Eolian_Typedecl const* decl)
{
if (!decl)
@@ -108,6 +130,22 @@ enum class class_type
regular, abstract_, mixin, interface_
};
+inline std::ostream& operator<<(std::ostream& s, class_type t)
+{
+ switch(t)
+ {
+ case class_type::regular:
+ return s << "regular";
+ case class_type::abstract_:
+ return s << "abstract_";
+ case class_type::mixin:
+ return s << "mixin";
+ case class_type::interface_:
+ return s << "interface_";
+ };
+ return s;
+}
+
struct klass_name
{
std::vector<std::string> namespaces;
@@ -116,6 +154,14 @@ struct klass_name
class_type type;
std::string klass_get_name;
+ friend inline std::ostream& operator<<(std::ostream& s, klass_name const& name)
+ {
+ s << "[ namespaces: {";
+ std::copy(name.namespaces.begin(), name.namespaces.end(), std::ostream_iterator<std::string>(s, ","));
+ return s << "}, eolian_name: " << name.eolian_name << " base_qualifier: " << name.base_qualifier
+ << " type: " << name.type << " klass_get_name: " << name.klass_get_name << "]";
+ }
+
klass_name() {
}
@@ -272,6 +318,14 @@ struct regular_type_def
bool is_alias() const { return is_type(typedecl_type::alias); }
bool is_function_ptr() const { return is_type(typedecl_type::function_ptr); }
+ friend inline std::ostream& operator<<(std::ostream& s, regular_type_def const& def)
+ {
+ s << "[ base_type: " << def.base_type << " base_qualifier: " << def.base_qualifier
+ << " namespaces: ";
+ std::copy(def.namespaces.begin(), def.namespaces.end(), std::ostream_iterator<std::string>(s, ", "));
+ return s << " type_type: " << def.type_type << " is_undefined " << def.is_undefined << "]";
+ }
+
std::string base_type;
qualifier_def base_qualifier;
std::vector<std::string> namespaces;
@@ -292,6 +346,13 @@ struct complex_type_def
{
regular_type_def outer;
std::vector<type_def> subtypes;
+
+ friend inline std::ostream& operator<<(std::ostream& s, complex_type_def const& def)
+ {
+ s << "[ outer " << def.outer << " subtypes: {";
+ std::copy(def.subtypes.begin(), def.subtypes.end(), std::ostream_iterator<type_def>(s, ", "));
+ return s << "}]";
+ }
};
inline bool operator==(complex_type_def const& lhs, complex_type_def const& rhs)
@@ -326,6 +387,12 @@ struct type_def
{
return lhs.c_type < rhs.c_type;
}
+ friend inline std::ostream& operator<<(std::ostream& s, type_def const& rhs)
+ {
+ return s << "[ original: " << rhs.original_type << " c_type "
+ << rhs.c_type << " has_own " << rhs.has_own << " is_ptr "
+ << rhs.is_ptr << "]";
+ }
};
struct 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
{
}
+ public static void return_null_object()
+ {
+ var testing = new Dummy.TestObject();
+ var o1 = testing.ReturnNullObject();
+ Test.Assert(o1 == null);
+ }
+
//
// Test cases:
//
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
return: Dummy.Test_Object;
}
+ return_null_object {
+ return: Dummy.Test_Object;
+ }
+
int_out {
params {
@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 @@
+{
+ "runtimeOptions": {
+ "tfm": "netcoreapp2.0",
+ "framework": {
+ "name": "Microsoft.NETCore.App",
+ "version": "2.0.0"
+ }
+ }
+}
+
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
return obj;
}
+Efl_Object *_dummy_test_object_return_null_object(Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd)
+{
+ return NULL;
+}
+
void _dummy_test_object_int_out(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd, int x, int *y)
{
*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
'@INPUT@'])
endforeach
+if (cs_is_dotnet)
efl_mono_test = library('efl_mono_test',
eo_file_targets,
link_with : [efl_mono],
+ runtime_assemblies : runtime_assemblies
)
+else
+efl_mono_test = library('efl_mono_test',
+ eo_file_targets,
+ link_with : [efl_mono],
+)
+endif
efl_mono_src = [
'Main.cs',
@@ -60,14 +68,43 @@ efl_mono_src = [
'Inheritance.cs',
]
+if (cs_is_dotnet)
efl_mono_suite = executable('efl-mono-suite',
efl_mono_src,
link_with : [efl_mono, efl_mono_test],
+ runtime_assemblies : runtime_assemblies
)
+else
+efl_mono_suite = executable('efl-mono-suite',
+ efl_mono_src,
+ link_with : [efl_mono, efl_mono_test],
+)
+endif
env = environment()
env.set('MONO_PATH', efl_mono_test_suite_path )
+if (cs_is_dotnet)
+env.set('LD_LIBRARY_PATH', efl_mono_test_suite_path )
+copy_prog = find_program(['cp', 'copy'])
+
+configure_file(input : 'efl-mono-suite.runtimeconfig.json',
+ output : 'efl-mono-suite.runtimeconfig.json',
+ copy : true)
+
+custom_target('copy_efl_mono_dll',
+ build_by_default : true,
+ input : efl_mono,
+ output : efl_mono.full_path().split('/')[-1],
+ command : [copy_prog, '@INPUT@', '@OUTPUT@'])
+
+custom_target('copy_efl_mono_lib_dll',
+ build_by_default : true,
+ input : efl_mono_lib,
+ output : efl_mono_lib.full_path().split('/')[-1],
+ command : [copy_prog, '@INPUT@', '@OUTPUT@'])
+endif
+
config_libs = ['eina', 'ecore', 'eo', 'efl', 'evas', 'eldbus', 'elementary']
load_lib = ''