[runtime] Implement support for passing icall methods as delegates in pinvoke. Fixes...
authorZoltan Varga <vargaz@gmail.com>
Sat, 19 Mar 2016 12:03:31 +0000 (13:03 +0100)
committerZoltan Varga <vargaz@gmail.com>
Sat, 19 Mar 2016 12:03:31 +0000 (13:03 +0100)
mono/metadata/marshal.c
mono/tests/libtest.c
mono/tests/pinvoke3.cs

index 696b97deca31c7385e56335cb44f4c2af65aa062..c2362db3de954e95eed36aa5968e89567c667942 100644 (file)
@@ -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
index c0d094fc56f1f2a262d9a42d77ccf0e67c01fff2..dbd2e9ad1cc108d8ee2ebbb383738f9b84999af4 100644 (file)
@@ -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)
 {
index 376e2000187f834b4b5ce0516fa1249cb5ced8cb..e0dca2c0e0ea72bc5a15555c392dec2fe38d15c3 100644 (file)
@@ -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;
+       }
 }