felipealmeida pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=3fd1566a088f167759703bdc0a099eeb907d3181
commit 3fd1566a088f167759703bdc0a099eeb907d3181 Author: Lauro Moura <lauromo...@expertisesolutions.com.br> Date: Wed Mar 21 22:43:21 2018 -0300 csharp: Provisionally fix conversion of eina.Value When we have an eina.Value_Native (representing an Eina_Value passed by value) and assign it to an eina.Value (a class with an IntPtr to an underlying Eina_Value) we copy it so the eina.Value can take ownership and free the data normally. A possibly better alternative would be adding an extra flag to eina.Value (something like OwnsPointer) to check whether we should free the struct we point to or not. --- src/bindings/mono/eina_mono/eina_value.cs | 12 +++++++++++- src/tests/efl_mono/Value.cs | 10 ++++++++++ src/tests/efl_mono/ValueEolian.cs | 24 ++++++++++++++++++++++++ src/tests/efl_mono/libefl_mono_native_test.c | 5 +++++ src/tests/efl_mono/test_testing.eo | 6 ++++++ 5 files changed, 56 insertions(+), 1 deletion(-) diff --git a/src/bindings/mono/eina_mono/eina_value.cs b/src/bindings/mono/eina_mono/eina_value.cs index a31d832919..50ff9457ef 100644 --- a/src/bindings/mono/eina_mono/eina_value.cs +++ b/src/bindings/mono/eina_mono/eina_value.cs @@ -325,6 +325,10 @@ static internal class UnsafeNativeMethods { [return: MarshalAsAttribute(UnmanagedType.U1)] internal static extern bool eina_value_pset_wrapper(IntPtr handle, ref eina.EinaNative.Value_List ptr); + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_copy(IntPtr src, IntPtr dest); + // Supported types // 8 bits byte @@ -707,12 +711,18 @@ public class Value : IDisposable, IComparable<Value>, IEquatable<Value> public Value(Value_Native value) { this.Handle = MemoryNative.Alloc(Marshal.SizeOf(typeof(Value_Native))); + IntPtr tmp = MemoryNative.Alloc(Marshal.SizeOf(typeof(Value_Native))); try { - Marshal.StructureToPtr(value, this.Handle, false); + Marshal.StructureToPtr(value, tmp, false); // Can't get the address of a struct directly. + if (!eina_value_copy(tmp, this.Handle)) + throw new System.InvalidOperationException("Failed to copy value to managed memory."); } catch { MemoryNative.Free(this.Handle); throw; + } finally { + MemoryNative.Free(tmp); } + this.Ownership = Ownership.Managed; } diff --git a/src/tests/efl_mono/Value.cs b/src/tests/efl_mono/Value.cs index 4744aa2ad7..018019b151 100644 --- a/src/tests/efl_mono/Value.cs +++ b/src/tests/efl_mono/Value.cs @@ -800,6 +800,16 @@ public static class TestEinaValue { } } + public static void TestStringThroughValue() { + // Check if Value_Native->Value doesn't try to free the pointed string. + using(eina.Value value_ptr = new eina.Value(eina.ValueType.String)) { + string payload = "Something"; + value_ptr.Set(payload); + eina.Value_Native byvalue = value_ptr; + eina.Value another_value_ptr = byvalue; + } + } + // FIXME Add remaining list tests diff --git a/src/tests/efl_mono/ValueEolian.cs b/src/tests/efl_mono/ValueEolian.cs index 0f8e1fa869..f39438937f 100644 --- a/src/tests/efl_mono/ValueEolian.cs +++ b/src/tests/efl_mono/ValueEolian.cs @@ -109,6 +109,30 @@ public static class TestEinaValueEolian { Test.AssertEquals(eina.Ownership.Managed, v_out.Ownership); } } + + private class ValueHandler : test.TestingInherit + { + public eina.Value value; + + public ValueHandler() : base(null) + { + value = null; + } + + public override void SetValue(eina.Value value) + { + this.value = value; + } + } + + public static void TestEolianEinaValueByValueConst() + { + ValueHandler obj = new ValueHandler(); + using (eina.Value val = new eina.Value(eina.ValueType.String)) { + obj.CallSetValue(val); + Test.AssertEquals(val, obj.value); + } + } } #pragma warning restore 1591 } diff --git a/src/tests/efl_mono/libefl_mono_native_test.c b/src/tests/efl_mono/libefl_mono_native_test.c index ce6865213f..f16c8957c3 100644 --- a/src/tests/efl_mono/libefl_mono_native_test.c +++ b/src/tests/efl_mono/libefl_mono_native_test.c @@ -3648,6 +3648,11 @@ void _test_testing_set_value(EINA_UNUSED Eo *obj, Test_Testing_Data *pd, Eina_Va eina_value_copy(&value, pd->stored_value); } +void _test_testing_call_set_value(Eo *obj, EINA_UNUSED Test_Testing_Data *pd, const Eina_Value v) +{ + test_testing_set_value(obj, v); +} + Eina_Value *_test_testing_get_value_ptr_own(EINA_UNUSED Eo *obj, Test_Testing_Data *pd) { Eina_Value *val = pd->stored_value; diff --git a/src/tests/efl_mono/test_testing.eo b/src/tests/efl_mono/test_testing.eo index 725d3cec69..5d1e7aa503 100644 --- a/src/tests/efl_mono/test_testing.eo +++ b/src/tests/efl_mono/test_testing.eo @@ -1327,6 +1327,12 @@ class Test.Testing (Efl.Object, Efl.Part) { } } + call_set_value { + params { + value: const(any_value); + } + } + get_value_ptr_own { return: any_value_ptr @owned; } --