From: Zoltan Varga Date: Sat, 19 Mar 2016 12:03:31 +0000 (+0100) Subject: [runtime] Implement support for passing icall methods as delegates in pinvoke. Fixes... X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=c736aba5c94c20e6faad6b736f8e3a834e26d95f;p=mono.git [runtime] Implement support for passing icall methods as delegates in pinvoke. Fixes #39347. --- diff --git a/mono/metadata/marshal.c b/mono/metadata/marshal.c index 696b97deca3..c2362db3de9 100644 --- a/mono/metadata/marshal.c +++ b/mono/metadata/marshal.c @@ -352,7 +352,7 @@ mono_delegate_to_ftnptr (MonoDelegate *delegate) if (delegate->method_is_virtual) method = mono_object_get_virtual_method (delegate->target, method); - if (mono_method_signature (method)->pinvoke) { + if (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) { const char *exc_class, *exc_arg; gpointer ftnptr; @@ -8226,7 +8226,7 @@ mono_marshal_get_managed_wrapper (MonoMethod *method, MonoClass *delegate_klass, EmitMarshalContext m; g_assert (method != NULL); - g_assert (!mono_method_signature (method)->pinvoke); + g_assert (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)); /* * FIXME: Should cache the method+delegate type pair, since the same method diff --git a/mono/tests/libtest.c b/mono/tests/libtest.c index c0d094fc56f..dbd2e9ad1cc 100644 --- a/mono/tests/libtest.c +++ b/mono/tests/libtest.c @@ -1117,6 +1117,14 @@ mono_test_marshal_virtual_delegate (VirtualDelegate del) return del (42); } +typedef char* (STDCALL *IcallDelegate) (const char *); +LIBTEST_API int STDCALL +mono_test_marshal_icall_delegate (IcallDelegate del) +{ + char *res = del ("ABC"); + return strcmp (res, "ABC") == 0 ? 0 : 1; +} + LIBTEST_API int STDCALL mono_test_marshal_stringbuilder (char *s, int n) { diff --git a/mono/tests/pinvoke3.cs b/mono/tests/pinvoke3.cs index 376e2000187..e0dca2c0e0e 100644 --- a/mono/tests/pinvoke3.cs +++ b/mono/tests/pinvoke3.cs @@ -194,6 +194,11 @@ public class Tests { [DllImport ("libtest", EntryPoint="mono_test_marshal_virtual_delegate")] public static extern int mono_test_marshal_virtual_delegate (VirtualDelegate del); + [DllImport ("libtest", EntryPoint="mono_test_marshal_icall_delegate")] + public static extern int mono_test_marshal_icall_delegate (IcallDelegate del); + + public delegate string IcallDelegate (IntPtr p); + public delegate int TestDelegate (int a, ref SimpleStruct ss, int b); public delegate SimpleStruct SimpleDelegate2 (SimpleStruct ss); @@ -1161,4 +1166,12 @@ public class Tests { return mono_test_marshal_virtual_delegate (b.get_del ()); } + + public static int test_0_icall_delegate () { + var m = typeof (Marshal).GetMethod ("PtrToStringAnsi", new Type[] { typeof (IntPtr) }); + + return mono_test_marshal_icall_delegate ((IcallDelegate)Delegate.CreateDelegate (typeof (IcallDelegate), m)); + Console.WriteLine (m); + return 0; + } }