From: Zoltan Varga Date: Wed, 4 Nov 2015 21:27:29 +0000 (-0500) Subject: [runtime] Implement native-to-managed marshalling of byref delegate arguments. Fixes... X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=d8d944c72c4ed605f5a587688e5303704b1044b5;p=mono.git [runtime] Implement native-to-managed marshalling of byref delegate arguments. Fixes #35545. --- diff --git a/mono/metadata/marshal.c b/mono/metadata/marshal.c index 78ed91e9e72..fa1807cd77b 100644 --- a/mono/metadata/marshal.c +++ b/mono/metadata/marshal.c @@ -5625,10 +5625,11 @@ emit_marshal_object (EmitMarshalContext *m, int argnum, MonoType *t, conv_arg = mono_mb_add_local (mb, &klass->byval_arg); if (klass->delegate) { - g_assert (!t->byref); mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX); mono_mb_emit_op (mb, CEE_MONO_CLASSCONST, klass); mono_mb_emit_ldarg (mb, argnum); + if (t->byref) + mono_mb_emit_byte (mb, CEE_LDIND_I); mono_mb_emit_icall (mb, conv_to_icall (MONO_MARSHAL_CONV_FTN_DEL)); mono_mb_emit_stloc (mb, conv_arg); break; @@ -5701,6 +5702,16 @@ emit_marshal_object (EmitMarshalContext *m, int argnum, MonoType *t, break; case MARSHAL_ACTION_MANAGED_CONV_OUT: + if (klass->delegate) { + if (t->byref) { + mono_mb_emit_ldarg (mb, argnum); + mono_mb_emit_ldloc (mb, conv_arg); + mono_mb_emit_icall (mb, conv_to_icall (MONO_MARSHAL_CONV_DEL_FTN)); + mono_mb_emit_byte (mb, CEE_STIND_I); + break; + } + } + if (t->byref) { /* Check for null */ mono_mb_emit_ldloc (mb, conv_arg); diff --git a/mono/tests/libtest.c b/mono/tests/libtest.c index aa58c852c36..7a6f7d1e172 100644 --- a/mono/tests/libtest.c +++ b/mono/tests/libtest.c @@ -876,6 +876,18 @@ mono_test_marshal_return_delegate (SimpleDelegate delegate) return delegate; } +typedef int DelegateByrefDelegate (void *); + +LIBTEST_API int STDCALL +mono_test_marshal_delegate_ref_delegate (DelegateByrefDelegate del) +{ + int (*ptr) (int i); + + del (&ptr); + + return ptr (54); +} + static int STDCALL return_plus_one (int i) { diff --git a/mono/tests/pinvoke3.cs b/mono/tests/pinvoke3.cs index ae64d16e090..4b9a4b7f49a 100644 --- a/mono/tests/pinvoke3.cs +++ b/mono/tests/pinvoke3.cs @@ -188,6 +188,9 @@ public class Tests { [DllImport ("libtest", EntryPoint="mono_test_marshal_return_delegate_delegate")] public static extern int mono_test_marshal_return_delegate_delegate (ReturnDelegateDelegate d); + [DllImport ("libtest", EntryPoint="mono_test_marshal_delegate_ref_delegate")] + public static extern int mono_test_marshal_delegate_ref_delegate (DelegateByrefDelegate del); + public delegate int TestDelegate (int a, ref SimpleStruct ss, int b); public delegate SimpleStruct SimpleDelegate2 (SimpleStruct ss); @@ -210,6 +213,8 @@ public class Tests { public delegate return_int_delegate ReturnDelegateDelegate (); + public delegate int DelegateByrefDelegate (ref return_int_delegate del); + public static int Main () { return TestDriver.RunTests (typeof (Tests)); } @@ -333,6 +338,20 @@ public class Tests { return mono_test_marshal_return_delegate_delegate (new ReturnDelegateDelegate (return_delegate)); } + public static int return_plus_1 (int i) { + return i + 1; + } + + public static int ref_delegate_delegate (ref return_int_delegate del) { + del = return_plus_1; + return 0; + } + + public static int test_55_marshal_delegate_ref_delegate () { + var del = new DelegateByrefDelegate (ref_delegate_delegate); + return mono_test_marshal_delegate_ref_delegate (del); + } + /* Passing and returning strings */ public delegate String ReturnStringDelegate (String s);