aboutsummaryrefslogtreecommitdiffstats
path: root/src/bindings
diff options
context:
space:
mode:
authorFelipe Magno de Almeida <felipe@expertisesolutions.com.br>2019-01-16 16:29:56 +0900
committerVitor Sousa <vitorsousa@expertisesolutions.com.br>2019-03-01 23:58:56 -0300
commitf392c5a4363cf09e8c0e50a42c46416a09a72c74 (patch)
tree1966addc0a769679e9dfa641df816c80d243651b /src/bindings
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
Diffstat (limited to 'src/bindings')
-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
17 files changed, 746 insertions, 212 deletions
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())