forked from enlightenment/efl
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.
This commit is contained in:
parent
e2fafe5b0c
commit
3fd1566a08
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue