aboutsummaryrefslogtreecommitdiffstats
path: root/src/tests
diff options
context:
space:
mode:
authorLauro Moura <lauromoura@expertisesolutions.com.br>2018-03-15 20:32:39 -0300
committerFelipe Magno de Almeida <felipe@expertisesolutions.com.br>2018-03-16 11:12:49 -0300
commit2705ea853108a64edc9264c8e5d4c79e55aea001 (patch)
tree7cbb95f4667ce4fa3d6c44a7b8e0e196a1ca757c /src/tests
parentcsharp: Change policy on ptr(struct) owned calls (diff)
downloadefl-2705ea853108a64edc9264c8e5d4c79e55aea001.tar.gz
csharp: Fix support for ptr(structs)
In general, ptr(struct) parameters behavior depends whether the parameter has the @owned modifier or not. If there is no @owned parameter (meaning no transfer of ownership happens) and it is a "complex" struct, with reference type fields (like strings), the struct is converted to the respective <Struct>Internal struct and passed with "ref" to the DllImport'd function. For @in parameters, after the function it returns, this intermediate struct is converted to the public struct type and assigned to the original parameter, updating it to the external world. When we have ownership transfers, the structure is copied to unmanaged memory and given to the callee. We can't send managed memory directly as the callee may try to free it. On the managed side, the original struct is left to be garbage collected normally.
Diffstat (limited to 'src/tests')
-rw-r--r--src/tests/efl_mono/BasicDirection.cs34
-rw-r--r--src/tests/efl_mono/Structs.cs244
-rw-r--r--src/tests/efl_mono/libefl_mono_native_test.c124
-rw-r--r--src/tests/efl_mono/test_testing.eo154
4 files changed, 462 insertions, 94 deletions
diff --git a/src/tests/efl_mono/BasicDirection.cs b/src/tests/efl_mono/BasicDirection.cs
new file mode 100644
index 0000000000..cf7634d09e
--- /dev/null
+++ b/src/tests/efl_mono/BasicDirection.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Runtime.InteropServices;
+using System.Linq;
+
+namespace TestSuite
+{
+
+class TestIntDirections
+{
+ public static void simple_out()
+ {
+ int original = 1984;
+ int received;
+ test.Testing t = new test.TestingConcrete();
+
+ t.IntOut(original, out received);
+
+ Test.AssertEquals(-original, received);
+ }
+
+ public static void simple_ptr_out()
+ {
+ int original = 1984;
+ int received;
+ test.Testing t = new test.TestingConcrete();
+
+ t.IntPtrOut(original, out received);
+
+ Test.AssertEquals(original*2, received);
+ }
+}
+
+}
+
diff --git a/src/tests/efl_mono/Structs.cs b/src/tests/efl_mono/Structs.cs
index 07917d0c56..20707c141b 100644
--- a/src/tests/efl_mono/Structs.cs
+++ b/src/tests/efl_mono/Structs.cs
@@ -266,38 +266,54 @@ class TestStructs
Test.Assert(r, "Function returned false");
}
- // public static void simple_ptr_in()
- // {
- // var simple = structSimpleWithValues();
- // test.Testing t = new test.TestingConcrete();
- // bool r = t.struct_simple_ptr_in(simple);
- // Test.Assert(r, "Function returned false");
- // }
+ public static void simple_ptr_in()
+ {
+ var simple = structSimpleWithValues();
+ int original = simple.Fint;
+ simple.Fstring = "Struct Ptr In";
+ test.Testing t = new test.TestingConcrete();
+ Test.Assert(t.StructSimplePtrIn(ref simple));
+ Test.AssertEquals(-original, simple.Fint);
+ Test.AssertEquals("nI rtP tcurtS", simple.Fstring);
+ }
- // public static void simple_ptr_in_own()
- // {
- // var simple = structSimpleWithValues();
- // test.Testing t = new test.TestingConcrete();
- // bool r = t.struct_simple_ptr_in_own(simple);
- // Test.Assert(r, "Function returned false");
- // }
+ public static void simple_ptr_in_own()
+ {
+ var simple = structSimpleWithValues();
+ int original = simple.Fint;
+ simple.Fstring = "Struct Ptr In Own";
+ test.Testing t = new test.TestingConcrete();
+ test.StructSimple result = t.StructSimplePtrInOwn(ref simple);
+ Test.AssertEquals(-original, result.Fint);
+ Test.AssertEquals("nwO nI rtP tcurtS", result.Fstring);
+ }
public static void simple_out()
{
var simple = new test.StructSimple();
test.Testing t = new test.TestingConcrete();
- bool r = t.StructSimpleOut(ref simple);
+ bool r = t.StructSimpleOut(out simple);
Test.Assert(r, "Function returned false");
checkStructSimple(simple);
}
- // public static void simple_ptr_out()
- // {
- // }
+ public static void simple_ptr_out()
+ {
+ test.StructSimple simple;
+ test.Testing t = new test.TestingConcrete();
+ test.StructSimple result = t.StructSimplePtrOut(out simple);
+ Test.AssertEquals(result.Fint, simple.Fint);
+ Test.AssertEquals(result.Fstring, simple.Fstring);
+ }
- // public static void simple_ptr_out_own()
- // {
- // }
+ public static void simple_ptr_out_own()
+ {
+ test.StructSimple simple;
+ test.Testing t = new test.TestingConcrete();
+ test.StructSimple result = t.StructSimplePtrOutOwn(out simple);
+ Test.AssertEquals(result.Fint, simple.Fint);
+ Test.AssertEquals(simple.Fstring, "Ptr Out Own");
+ }
public static void simple_return()
{
@@ -306,14 +322,186 @@ class TestStructs
checkStructSimple(simple);
}
- // public static void simple_ptr_return()
- // {
- // }
+ public static void simple_ptr_return()
+ {
+ test.Testing t = new test.TestingConcrete();
+ var simple = t.StructSimplePtrReturn();
+ Test.AssertEquals(simple.Fstring, "Ret Ptr");
+ }
- // public static void simple_ptr_return_own()
- // {
- // }
+ public static void simple_ptr_return_own()
+ {
+ test.Testing t = new test.TestingConcrete();
+ var simple = t.StructSimplePtrReturnOwn();
+ Test.AssertEquals(simple.Fstring, "Ret Ptr Own");
+ }
+
+ public class StructReturner : test.TestingInherit
+ {
+ public test.StructSimple received;
+ public bool called;
+
+ public StructReturner() : base(null)
+ {
+ called = false;
+ received = default(test.StructSimple);
+ }
+
+ public override bool StructSimpleIn(test.StructSimple simple)
+ {
+ called = true;
+ received = simple;
+
+ return true;
+ }
+
+ public override bool StructSimplePtrIn(ref test.StructSimple simple)
+ {
+ called = true;
+ simple.Fstring = "Virtual Struct Ptr In";
+ return true;
+ }
+
+ public override test.StructSimple StructSimplePtrInOwn(ref test.StructSimple simple)
+ {
+ called = true;
+ received = simple;
+ return received;
+ }
+
+ public override bool StructSimpleOut(out test.StructSimple simple) {
+ called = true;
+ simple = new test.StructSimple();
+ simple.Fstring = "Virtual Struct Out";
+ return true;
+ }
+
+ public override test.StructSimple StructSimplePtrOut(out test.StructSimple simple) {
+ called = true;
+ // No way to explicitly define the ownership of the parameter.
+ simple = new test.StructSimple();
+ simple.Fstring = "Virtual Struct Ptr Out";
+ return simple;
+ }
+
+ public override test.StructSimple StructSimplePtrOutOwn(out test.StructSimple simple) {
+ called = true;
+ // No way to explicitly define the ownership of the parameter.
+ simple = new test.StructSimple();
+ simple.Fstring = "Virtual Struct Ptr Out Own";
+ return simple;
+ }
+
+ public override test.StructSimple StructSimpleReturn()
+ {
+ called = true;
+ var simple = new test.StructSimple();
+ simple.Fstring = "Virtual Struct Return";
+ return simple;
+ }
+
+ public override test.StructSimple StructSimplePtrReturn()
+ {
+ called = true;
+ var simple = new test.StructSimple();
+ simple.Fstring = "Virtual Struct Ptr Return";
+ return simple;
+ }
+
+ public override test.StructSimple StructSimplePtrReturnOwn()
+ {
+ called = true;
+ var simple = new test.StructSimple();
+ simple.Fstring = "Virtual Struct Ptr Return Own";
+ return simple;
+ }
+ }
+
+ public static void simple_in_virtual()
+ {
+ StructReturner t = new StructReturner();
+ var simple = structSimpleWithValues();
+ simple.Fstring = "Virtual Struct In";
+
+ t.CallStructSimpleIn(simple);
+ Test.Assert(t.called);
+ Test.AssertEquals(simple.Fstring, t.received.Fstring);
+ }
+
+ public static void simple_ptr_in_virtual()
+ {
+ StructReturner t = new StructReturner();
+ var simple = structSimpleWithValues();
+ string reference = "Virtual Struct Ptr In";
+
+ t.CallStructSimplePtrIn(ref simple);
+ Test.Assert(t.called);
+ Test.AssertEquals(simple.Fstring, reference);
+ }
+
+ public static void simple_ptr_in_own_virtual()
+ {
+ StructReturner t = new StructReturner();
+ var simple = structSimpleWithValues();
+ simple.Fstring = "Virtual Struct Ptr In Own";
+
+ t.CallStructSimplePtrInOwn(ref simple);
+ Test.Assert(t.called);
+ Test.AssertEquals(t.received.Fstring, simple.Fstring);
+ }
+
+ public static void simple_out_virtual()
+ {
+ StructReturner t = new StructReturner();
+ test.StructSimple simple;
+ t.CallStructSimpleOut(out simple);
+ Test.Assert(t.called, "override was not called");
+ Test.AssertEquals("Virtual Struct Out", simple.Fstring);
+ }
+
+ public static void simple_ptr_out_virtual()
+ {
+ StructReturner t = new StructReturner();
+ test.StructSimple simple;
+ t.CallStructSimplePtrOut(out simple);
+ Test.Assert(t.called, "override was not called");
+ Test.AssertEquals("Virtual Struct Ptr Out", simple.Fstring);
+ }
+
+ public static void simple_ptr_out_own_virtual()
+ {
+ StructReturner t = new StructReturner();
+ test.StructSimple simple;
+ t.CallStructSimplePtrOutOwn(out simple);
+ Test.Assert(t.called, "override was not called");
+ Test.AssertEquals("Virtual Struct Ptr Out Own", simple.Fstring);
+ }
+
+ public static void simple_return_virtual()
+ {
+ StructReturner t = new StructReturner();
+ test.StructSimple simple = t.CallStructSimpleReturn();
+ Test.Assert(t.called, "override was not called");
+ Test.AssertEquals("Virtual Struct Return", simple.Fstring);
+ }
+
+ public static void simple_ptr_return_virtual()
+ {
+ StructReturner t = new StructReturner();
+ test.StructSimple simple = t.CallStructSimplePtrReturn();
+ Test.Assert(t.called, "override was not called");
+ Test.AssertEquals("Virtual Struct Ptr Return", simple.Fstring);
+ }
+
+ public static void simple_ptr_return_own_virtual()
+ {
+ StructReturner t = new StructReturner();
+ test.StructSimple simple = t.CallStructSimplePtrReturnOwn();
+ Test.Assert(t.called, "override was not called");
+ Test.AssertEquals("Virtual Struct Ptr Return Own", simple.Fstring);
+ }
+ // Complex Structs
public static void complex_in()
{
var complex = structComplexWithValues();
@@ -334,7 +522,7 @@ class TestStructs
{
var complex = new test.StructComplex();
test.Testing t = new test.TestingConcrete();
- bool r = t.StructComplexOut(ref complex);
+ bool r = t.StructComplexOut(out complex);
Test.Assert(r, "Function returned false");
checkStructComplex(complex);
}
diff --git a/src/tests/efl_mono/libefl_mono_native_test.c b/src/tests/efl_mono/libefl_mono_native_test.c
index f96666380b..04fd12053f 100644
--- a/src/tests/efl_mono/libefl_mono_native_test.c
+++ b/src/tests/efl_mono/libefl_mono_native_test.c
@@ -44,7 +44,8 @@ typedef struct Test_Testing_Data
Eina_Free_Cb free_cb;
Eina_Error error_code;
Eina_Value *stored_value;
-
+ Test_StructSimple stored_struct;
+ int stored_int;
} Test_Testing_Data;
typedef struct Test_Numberwrapper_Data
@@ -100,6 +101,17 @@ Efl_Object *_test_testing_return_object(Eo *obj, EINA_UNUSED Test_Testing_Data *
return obj;
}
+void _test_testing_int_out(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd, int x, int *y)
+{
+ *y = -x;
+}
+
+void _test_testing_int_ptr_out(EINA_UNUSED Eo *obj, Test_Testing_Data *pd, int x, int **y)
+{
+ pd->stored_int = x * 2;
+ *y = &pd->stored_int;
+}
+
const char *_test_testing_in_string(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd, const char *str)
{
const char *ret = malloc(sizeof(char)*(strlen(str) + 1));
@@ -3342,20 +3354,34 @@ Eina_Bool _test_testing_struct_simple_in(EINA_UNUSED Eo *obj, EINA_UNUSED Test_T
return check_and_modify_struct_simple(&simple);
}
+static void _reverse_string(char *str)
+{
+ int len = strlen(str);
+ if (len > 0) {
+ for (int i=0, k=len-1; i < len/2; i++, k--) {
+ char tmp = str[k];
+ str[k] = str[i];
+ str[i] = tmp;
+ }
+ }
+}
+
EOLIAN
Eina_Bool _test_testing_struct_simple_ptr_in(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd, Test_StructSimple *simple)
{
- (void) simple;
- EINA_LOG_ERR("Not implemented!");
- return EINA_FALSE;
+ simple->fint = -simple->fint;
+ _reverse_string(simple->fstring);
+ return EINA_TRUE;
}
EOLIAN
-Eina_Bool _test_testing_struct_simple_ptr_in_own(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd, Test_StructSimple *simple)
+Test_StructSimple _test_testing_struct_simple_ptr_in_own(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd, Test_StructSimple *simple)
{
- (void) simple;
- EINA_LOG_ERR("Not implemented!");
- return EINA_FALSE;
+ Test_StructSimple ret = *simple;
+ free(simple);
+ ret.fint = -ret.fint;
+ _reverse_string(ret.fstring);
+ return ret;
}
EOLIAN
@@ -3373,19 +3399,20 @@ Eina_Bool _test_testing_struct_simple_out(EINA_UNUSED Eo *obj, EINA_UNUSED Test_
}
EOLIAN
-Eina_Bool _test_testing_struct_simple_ptr_out(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd, Test_StructSimple **simple)
+Test_StructSimple _test_testing_struct_simple_ptr_out(EINA_UNUSED Eo *obj, Test_Testing_Data *pd, Test_StructSimple **simple)
{
- (void) simple;
- EINA_LOG_ERR("Not implemented!");
- return EINA_FALSE;
+ struct_simple_with_values(&pd->stored_struct);
+ *simple = &pd->stored_struct;
+ return **simple;
}
EOLIAN
-Eina_Bool _test_testing_struct_simple_ptr_out_own(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd, Test_StructSimple **simple)
+Test_StructSimple _test_testing_struct_simple_ptr_out_own(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd, Test_StructSimple **simple)
{
- (void) simple;
- EINA_LOG_ERR("Not implemented!");
- return EINA_FALSE;
+ *simple = malloc(sizeof(Test_StructSimple));
+ struct_simple_with_values(*simple);
+ (*simple)->fstring = "Ptr Out Own";
+ return **simple;
}
EOLIAN
@@ -3399,15 +3426,72 @@ Test_StructSimple _test_testing_struct_simple_return(EINA_UNUSED Eo *obj, EINA_U
EOLIAN
Test_StructSimple *_test_testing_struct_simple_ptr_return(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd)
{
- EINA_LOG_ERR("Not implemented!");
- return NULL;
+ struct_simple_with_values(&pd->stored_struct);
+ pd->stored_struct.fstring = "Ret Ptr";
+ return &pd->stored_struct;
}
EOLIAN
Test_StructSimple *_test_testing_struct_simple_ptr_return_own(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd)
{
- EINA_LOG_ERR("Not implemented!");
- return NULL;
+ Test_StructSimple *ret = malloc(sizeof(Test_StructSimple));
+ struct_simple_with_values(ret);
+ ret->fstring = "Ret Ptr Own";
+ return ret;
+}
+
+EOLIAN
+void _test_testing_call_struct_simple_in(Eo *obj, EINA_UNUSED Test_Testing_Data *pd, Test_StructSimple simple)
+{
+ test_testing_struct_simple_in(obj, simple);
+}
+
+EOLIAN
+void _test_testing_call_struct_simple_ptr_in(Eo *obj, EINA_UNUSED Test_Testing_Data *pd, Test_StructSimple *simple)
+{
+ test_testing_struct_simple_ptr_in(obj, simple);
+}
+
+EOLIAN
+void _test_testing_call_struct_simple_ptr_in_own(Eo *obj, EINA_UNUSED Test_Testing_Data *pd, Test_StructSimple *simple)
+{
+ test_testing_struct_simple_ptr_in_own(obj, simple);
+}
+
+EOLIAN
+void _test_testing_call_struct_simple_out(Eo *obj, EINA_UNUSED Test_Testing_Data *pd, Test_StructSimple *simple)
+{
+ test_testing_struct_simple_out(obj, simple);
+}
+
+EOLIAN
+void _test_testing_call_struct_simple_ptr_out(Eo *obj, EINA_UNUSED Test_Testing_Data *pd, Test_StructSimple **simple)
+{
+ test_testing_struct_simple_ptr_out(obj, simple);
+}
+
+EOLIAN
+void _test_testing_call_struct_simple_ptr_out_own(Eo *obj, EINA_UNUSED Test_Testing_Data *pd, Test_StructSimple **simple)
+{
+ test_testing_struct_simple_ptr_out_own(obj, simple);
+}
+
+EOLIAN
+Test_StructSimple _test_testing_call_struct_simple_return(Eo *obj, EINA_UNUSED Test_Testing_Data *pd)
+{
+ return test_testing_struct_simple_return(obj);
+}
+
+EOLIAN
+Test_StructSimple *_test_testing_call_struct_simple_ptr_return(Eo *obj, EINA_UNUSED Test_Testing_Data *pd)
+{
+ return test_testing_struct_simple_ptr_return(obj);
+}
+
+EOLIAN
+Test_StructSimple *_test_testing_call_struct_simple_ptr_return_own(Eo *obj, EINA_UNUSED Test_Testing_Data *pd)
+{
+ return test_testing_struct_simple_ptr_return_own(obj);
}
// with complex types
diff --git a/src/tests/efl_mono/test_testing.eo b/src/tests/efl_mono/test_testing.eo
index a65b4db8da..c2d3edcd2e 100644
--- a/src/tests/efl_mono/test_testing.eo
+++ b/src/tests/efl_mono/test_testing.eo
@@ -87,6 +87,20 @@ class Test.Testing (Efl.Object) {
return: Test.Testing;
}
+ int_out {
+ params {
+ @in x: int;
+ @out y: int;
+ }
+ }
+
+ int_ptr_out {
+ params {
+ @in x: int;
+ @out y: ptr(int);
+ }
+ }
+
in_stringshare {
params {
@in v: stringshare;
@@ -1355,19 +1369,19 @@ class Test.Testing (Efl.Object) {
return: bool;
}
- // struct_simple_ptr_in {
- // params {
- // @in simple: ptr(Test.StructSimple);
- // }
- // return: bool;
- // }
- //
- // struct_simple_ptr_in_own {
- // params {
- // @in simple: ptr(Test.StructSimple) @owned;
- // }
- // return: bool;
- // }
+ struct_simple_ptr_in {
+ params {
+ @in simple: ptr(Test.StructSimple);
+ }
+ return: bool;
+ }
+
+ struct_simple_ptr_in_own {
+ params {
+ @in simple: ptr(Test.StructSimple) @owned;
+ }
+ return: Test.StructSimple;
+ }
struct_simple_out {
params {
@@ -1376,31 +1390,79 @@ class Test.Testing (Efl.Object) {
return: bool;
}
- // struct_simple_ptr_out {
- // params {
- // @out simple: ptr(Test.StructSimple);
- // }
- // return: bool;
- // }
- //
- // struct_simple_ptr_out_own {
- // params {
- // @out simple: ptr(Test.StructSimple) @owned;
- // }
- // return: bool;
- // }
+ struct_simple_ptr_out {
+ params {
+ @out simple: ptr(Test.StructSimple);
+ }
+ return: Test.StructSimple;
+ }
+
+ struct_simple_ptr_out_own {
+ params {
+ @out simple: ptr(Test.StructSimple) @owned;
+ }
+ return: Test.StructSimple;
+ }
struct_simple_return {
return: Test.StructSimple;
}
- // struct_simple_ptr_return {
- // return: ptr(Test.StructSimple);
- // }
- //
- // struct_simple_ptr_return_own {
- // return: ptr(Test.StructSimple) @owned;
- // }
+ struct_simple_ptr_return {
+ return: ptr(Test.StructSimple);
+ }
+
+ struct_simple_ptr_return_own {
+ return: ptr(Test.StructSimple) @owned;
+ }
+
+ call_struct_simple_in {
+ params {
+ @in simple: Test.StructSimple;
+ }
+ }
+
+ call_struct_simple_ptr_in {
+ params {
+ @in simple: ptr(Test.StructSimple);
+ }
+ }
+
+ call_struct_simple_ptr_in_own {
+ params {
+ @in simple: ptr(Test.StructSimple) @owned;
+ }
+ }
+
+ call_struct_simple_out {
+ params {
+ @out simple: Test.StructSimple;
+ }
+ }
+
+ call_struct_simple_ptr_out {
+ params {
+ @out simple: ptr(Test.StructSimple);
+ }
+ }
+
+ call_struct_simple_ptr_out_own {
+ params {
+ @out simple: ptr(Test.StructSimple) @owned;
+ }
+ }
+
+ call_struct_simple_return {
+ return: Test.StructSimple;
+ }
+
+ call_struct_simple_ptr_return {
+ return: ptr(Test.StructSimple);
+ }
+
+ call_struct_simple_ptr_return_own {
+ return: ptr(Test.StructSimple) @owned;
+ }
struct_complex_in {
params {
@@ -1409,19 +1471,19 @@ class Test.Testing (Efl.Object) {
return: bool;
}
- // struct_complex_ptr_in {
- // params {
- // @in complex: ptr(Test.StructComplex);
- // }
- // return: bool;
- // }
- //
- // struct_complex_ptr_in_own {
- // params {
- // @in complex: ptr(Test.StructComplex) @owned;
- // }
- // return: bool;
- // }
+ struct_complex_ptr_in {
+ params {
+ @in complex: ptr(Test.StructComplex);
+ }
+ return: bool;
+ }
+
+ struct_complex_ptr_in_own {
+ params {
+ @in complex: ptr(Test.StructComplex) @owned;
+ }
+ return: bool;
+ }
struct_complex_out {
params {