forked from enlightenment/efl
csharp: Update string marshalers
Mostly done, needs work on strings being returned without ownership from C# to C.
This commit is contained in:
parent
52da69510f
commit
c1293edbd2
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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,86 @@ 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)
|
||||
{
|
||||
// No need to free. The Native side will keep the ownership.
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
@ -76,13 +136,57 @@ namespace Efl
|
|||
{
|
||||
if (marshaler == null)
|
||||
{
|
||||
marshaler = new StringKeepOwnershipMarshaler();
|
||||
marshaler = new StringOutPassOwnershipMarshaler();
|
||||
}
|
||||
|
||||
return marshaler;
|
||||
}
|
||||
|
||||
static private StringKeepOwnershipMarshaler 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)
|
||||
{
|
||||
}
|
||||
|
||||
public int GetNativeDataSize()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
internal static ICustomMarshaler GetInstance(string cookie)
|
||||
{
|
||||
if (marshaler == null)
|
||||
{
|
||||
marshaler = new StringOutKeepOwnershipMarshaler();
|
||||
}
|
||||
|
||||
return marshaler;
|
||||
}
|
||||
|
||||
static private ICustomMarshaler marshaler;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue