summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLauro Moura <lauromoura@expertisesolutions.com.br>2019-12-06 19:25:14 -0300
committerLauro Moura <lauromoura@expertisesolutions.com.br>2019-12-11 00:20:44 -0300
commitc1293edbd2a8bc85c7bc168c05b333c3b605d4c1 (patch)
tree3f32f5c602f33b34c7a9ced9fd920859ff305e16
parent52da69510fc65af427ca0892971b192247042583 (diff)
downloadefl-c1293edbd2a8bc85c7bc168c05b333c3b605d4c1.tar.gz
csharp: Update string marshalers
Mostly done, needs work on strings being returned without ownership from C# to C.
-rw-r--r--src/bin/eolian_mono/eolian/mono/marshall_annotation.hh23
-rw-r--r--src/bindings/mono/eina_mono/eina_environment.cs2
-rw-r--r--src/bindings/mono/eina_mono/eina_strbuf.cs4
-rw-r--r--src/bindings/mono/eina_mono/eina_value.cs2
-rw-r--r--src/bindings/mono/eo_mono/StringMarshalers.cs118
5 files changed, 126 insertions, 23 deletions
diff --git a/src/bin/eolian_mono/eolian/mono/marshall_annotation.hh b/src/bin/eolian_mono/eolian/mono/marshall_annotation.hh
index a9fc45d7da..3cd9f6d267 100644
--- a/src/bin/eolian_mono/eolian/mono/marshall_annotation.hh
+++ b/src/bin/eolian_mono/eolian/mono/marshall_annotation.hh
@@ -51,23 +51,22 @@ struct marshall_annotation_visitor_generate
eina::optional<bool> has_own;
std::function<std::string()> function;
};
- // These two tables are currently the same but will hold different marshallers
- // for @in and @out/return semantics in a future commit.
- match const parameter_match_table[] =
+
+ match const input_match_table[] =
{
// signed primitives
{"bool", nullptr, [] { return "MarshalAs(UnmanagedType.U1)"; }},
{"string", true, [] {
- return "MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringPassOwnershipMarshaler))";
+ return "MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringInPassOwnershipMarshaler))";
}},
{"string", false, [] {
- return "MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringKeepOwnershipMarshaler))";
+ return "MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringInKeepOwnershipMarshaler))";
}},
{"mstring", true, [] {
- return "MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringPassOwnershipMarshaler))";
+ return "MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringInPassOwnershipMarshaler))";
}},
{"mstring", false, [] {
- return "MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringKeepOwnershipMarshaler))";
+ return "MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringInKeepOwnershipMarshaler))";
}},
{"stringshare", true, [] {
return "MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringsharePassOwnershipMarshaler))";
@@ -96,16 +95,16 @@ struct marshall_annotation_visitor_generate
// signed primitives
{"bool", nullptr, [] { return "MarshalAs(UnmanagedType.U1)"; }},
{"string", true, [] {
- return "MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringPassOwnershipMarshaler))";
+ return "MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringOutPassOwnershipMarshaler))";
}},
{"string", false, [] {
- return "MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringKeepOwnershipMarshaler))";
+ return "MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringOutKeepOwnershipMarshaler))";
}},
{"mstring", true, [] {
- return "MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringPassOwnershipMarshaler))";
+ return "MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringOutPassOwnershipMarshaler))";
}},
{"mstring", false, [] {
- return "MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringKeepOwnershipMarshaler))";
+ return "MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringOutKeepOwnershipMarshaler))";
}},
{"stringshare", true, [] {
return "MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringsharePassOwnershipMarshaler))";
@@ -143,7 +142,7 @@ struct marshall_annotation_visitor_generate
return as_generator("[" << prefix << marshalTag << "]").generate(sink, nullptr, *context);
};
- const auto& match_table = is_return ? return_match_table : parameter_match_table;
+ const auto& match_table = (is_return || is_out) ? return_match_table : input_match_table;
if(eina::optional<bool> b = type_match::get_match(match_table, predicate, acceptCb))
{
diff --git a/src/bindings/mono/eina_mono/eina_environment.cs b/src/bindings/mono/eina_mono/eina_environment.cs
index 7cef31cbf1..a06417ca5a 100644
--- a/src/bindings/mono/eina_mono/eina_environment.cs
+++ b/src/bindings/mono/eina_mono/eina_environment.cs
@@ -43,7 +43,7 @@ internal static class Environment
internal static partial class NativeCustomExportFunctions
{
[DllImport(efl.Libs.CustomExports, CharSet=CharSet.Ansi)]
- [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringKeepOwnershipMarshaler))]
+ [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringOutKeepOwnershipMarshaler))]
public static extern string efl_mono_native_getenv(string name);
[DllImport(efl.Libs.CustomExports, CharSet=CharSet.Ansi)]
diff --git a/src/bindings/mono/eina_mono/eina_strbuf.cs b/src/bindings/mono/eina_mono/eina_strbuf.cs
index bdde9a911e..b29ffb3033 100644
--- a/src/bindings/mono/eina_mono/eina_strbuf.cs
+++ b/src/bindings/mono/eina_mono/eina_strbuf.cs
@@ -51,13 +51,13 @@ static internal class StrbufNativeMethods
[DllImport(efl.Libs.Eina, CharSet=CharSet.Ansi)]
[return:
MarshalAs(UnmanagedType.CustomMarshaler,
- MarshalTypeRef=typeof(Efl.Eo.StringPassOwnershipMarshaler))]
+ MarshalTypeRef=typeof(Efl.Eo.StringOutPassOwnershipMarshaler))]
internal static extern string eina_strbuf_string_steal(IntPtr buf);
[DllImport(efl.Libs.Eina, CharSet=CharSet.Ansi)]
[return:
MarshalAs(UnmanagedType.CustomMarshaler,
- MarshalTypeRef=typeof(Efl.Eo.StringKeepOwnershipMarshaler))]
+ MarshalTypeRef=typeof(Efl.Eo.StringOutKeepOwnershipMarshaler))]
internal static extern string eina_strbuf_string_get(IntPtr buf);
[DllImport(efl.Libs.Eina)]
diff --git a/src/bindings/mono/eina_mono/eina_value.cs b/src/bindings/mono/eina_mono/eina_value.cs
index 2a2508e08b..728bd64fcc 100644
--- a/src/bindings/mono/eina_mono/eina_value.cs
+++ b/src/bindings/mono/eina_mono/eina_value.cs
@@ -194,7 +194,7 @@ static internal class UnsafeNativeMethods
[DllImport(efl.Libs.Eina, CharSet=CharSet.Ansi)]
[return:
MarshalAs(UnmanagedType.CustomMarshaler,
- MarshalTypeRef=typeof(Efl.Eo.StringPassOwnershipMarshaler))]
+ MarshalTypeRef=typeof(Efl.Eo.StringOutPassOwnershipMarshaler))]
internal static extern string eina_value_to_string(IntPtr handle); // We take ownership of the returned string.
[DllImport(efl.Libs.CustomExports)]
diff --git a/src/bindings/mono/eo_mono/StringMarshalers.cs b/src/bindings/mono/eo_mono/StringMarshalers.cs
index 39188c138b..7851ed947b 100644
--- a/src/bindings/mono/eo_mono/StringMarshalers.cs
+++ b/src/bindings/mono/eo_mono/StringMarshalers.cs
@@ -5,8 +5,12 @@ namespace Efl
{
namespace Eo
{
- class StringPassOwnershipMarshaler : ICustomMarshaler
+ /// <summary>
+ /// Marshaler for <c>@in</c> parameters that have their ownership transfered.
+ /// </summary>
+ class StringInPassOwnershipMarshaler : ICustomMarshaler
{
+ // Called when C calls a C# method passing data to it
public object MarshalNativeToManaged(IntPtr pNativeData)
{
var ret = Eina.StringConversion.NativeUtf8ToManagedString(pNativeData);
@@ -14,16 +18,18 @@ namespace Efl
return ret;
}
+ // Called when C# calls a C method passing data to it
public IntPtr MarshalManagedToNative(object managedObj)
{
return Eina.MemoryNative.StrDup((string)managedObj);
}
+ // Called when the C call returns, cleaning the result from MarshalManagedToNative
public void CleanUpNativeData(IntPtr pNativeData)
{
- // No need to cleanup. C will take care of it.
}
+ // Called when the C# call returns, cleaning the result from MarshalNativeToManaged
public void CleanUpManagedData(object managedObj)
{
}
@@ -37,32 +43,130 @@ namespace Efl
{
if (marshaler == null)
{
- marshaler = new StringPassOwnershipMarshaler();
+ marshaler = new StringInPassOwnershipMarshaler();
}
return marshaler;
}
- static private StringPassOwnershipMarshaler marshaler;
+ static private ICustomMarshaler marshaler;
}
- class StringKeepOwnershipMarshaler: ICustomMarshaler
+ /// <summary>
+ /// Marshaler for <c>@in</c> parameters that do not change their ownership.
+ /// </summary>
+ class StringInKeepOwnershipMarshaler: ICustomMarshaler
{
+ // Called when C calls a C# method passing data to it
public object MarshalNativeToManaged(IntPtr pNativeData)
{
return Eina.StringConversion.NativeUtf8ToManagedString(pNativeData);
}
+ // Called when C# calls a C method passing data to it
public IntPtr MarshalManagedToNative(object managedObj)
{
return Eina.StringConversion.ManagedStringToNativeUtf8Alloc((string)managedObj);
}
+ // Called when the C call returns, cleaning the result from MarshalManagedToNative
+ public void CleanUpNativeData(IntPtr pNativeData)
+ {
+ Eina.MemoryNative.Free(pNativeData);
+ }
+
+ // Called when the C# call returns, cleaning the result from MarshalNativeToManaged
+ public void CleanUpManagedData(object managedObj)
+ {
+ // GC will should take care of it.
+ }
+
+ public int GetNativeDataSize()
+ {
+ return -1;
+ }
+
+ internal static ICustomMarshaler GetInstance(string cookie)
+ {
+ if (marshaler == null)
+ {
+ marshaler = new StringInKeepOwnershipMarshaler();
+ }
+
+ return marshaler;
+ }
+
+ static private ICustomMarshaler marshaler;
+ }
+
+ class StringOutPassOwnershipMarshaler : ICustomMarshaler
+ {
+ // Called when C# calls a C method and receives data from it
+ public object MarshalNativeToManaged(IntPtr pNativeData)
+ {
+ var ret = Eina.StringConversion.NativeUtf8ToManagedString(pNativeData);
+ // C gave us ownership. Let's free.
+ Eina.MemoryNative.Free(pNativeData);
+ return ret;
+ }
+
+ // Called when C calls a C# method and receives data from it
+ public IntPtr MarshalManagedToNative(object managedObj)
+ {
+ // As we're passing up the ownership, no need to free it.
+ return Eina.MemoryNative.StrDup((string)managedObj);
+ }
+
+ // Called when the C call returns, cleaning the result it gave to C#
+ public void CleanUpNativeData(IntPtr pNativeData)
+ {
+ }
+
+ // Called when the C# call returns, cleaning the result it gave to C.
+ public void CleanUpManagedData(object managedObj)
+ {
+ }
+
+ public int GetNativeDataSize()
+ {
+ return -1;
+ }
+
+ internal static ICustomMarshaler GetInstance(string cookie)
+ {
+ if (marshaler == null)
+ {
+ marshaler = new StringOutPassOwnershipMarshaler();
+ }
+
+ return marshaler;
+ }
+
+ static private ICustomMarshaler marshaler;
+ }
+
+ class StringOutKeepOwnershipMarshaler: ICustomMarshaler
+ {
+ // Called when C# calls a C method and receives data from it
+ public object MarshalNativeToManaged(IntPtr pNativeData)
+ {
+ return Eina.StringConversion.NativeUtf8ToManagedString(pNativeData);
+ }
+
+ // Called when C calls a C# method and receives data from it
+ public IntPtr MarshalManagedToNative(object managedObj)
+ {
+ // FIXME This will be the tricky one, as it can leak.
+ return Eina.StringConversion.ManagedStringToNativeUtf8Alloc((string)managedObj);
+ }
+
+ // Called when the C call returns, cleaning the result it gave to C#
public void CleanUpNativeData(IntPtr pNativeData)
{
// No need to free. The Native side will keep the ownership.
}
+ // Called when the C call returns, cleaning the result it gave to C#
public void CleanUpManagedData(object managedObj)
{
}
@@ -76,13 +180,13 @@ namespace Efl
{
if (marshaler == null)
{
- marshaler = new StringKeepOwnershipMarshaler();
+ marshaler = new StringOutKeepOwnershipMarshaler();
}
return marshaler;
}
- static private StringKeepOwnershipMarshaler marshaler;
+ static private ICustomMarshaler marshaler;
}
}