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;
       }

-- 


Reply via email to