merge -r 60814:60815
[mono.git] / mono / tests / pinvoke2.cs
index 36aa707a3378b7130b872a3160867299afecc27e..555846e8ac7dde4c0268ab7ca5c857caddb46598 100644 (file)
@@ -1,6 +1,7 @@
 using System;
 using System.Text;
 using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
 
 public class Tests {
 
@@ -97,6 +98,37 @@ public class Tests {
                public int i;
        }
 
+       [StructLayout(LayoutKind.Sequential)]
+       struct AsAnyStruct
+       {
+               public int i;
+               public int j;
+               public int k;
+               public String s;
+
+               public AsAnyStruct(int i, int j, int k, String s) {
+                       this.i = i;
+                       this.j = j;
+                       this.k = k;
+                       this.s = s;
+               }
+       }
+
+       [StructLayout(LayoutKind.Sequential)]
+       class AsAnyClass
+       {
+               public int i;
+               public int j;
+               public int k;
+               public String s;
+
+               public AsAnyClass(int i, int j, int k, String s) {
+                       this.i = i;
+                       this.j = j;
+                       this.k = k;
+               }
+       }
+
        [DllImport ("libnot-found", EntryPoint="not_found")]
        public static extern int mono_library_not_found ();
 
@@ -112,7 +144,7 @@ public class Tests {
        [DllImport ("libtest", EntryPoint="mono_test_marshal_char")]
        public static extern int mono_test_marshal_char (char a1);
 
-       [DllImport ("libtest", EntryPoint="mono_test_marshal_char_array")]
+       [DllImport ("libtest", EntryPoint="mono_test_marshal_char_array", CharSet=CharSet.Unicode)]
        public static extern int mono_test_marshal_char_array (char[] a1);
 
        [DllImport ("libtest", EntryPoint="mono_test_marshal_bool_byref")]
@@ -136,6 +168,9 @@ public class Tests {
        [DllImport ("libtest", EntryPoint="mono_test_marshal_inout_array")]
        public static extern int mono_test_marshal_inout_array ([In, Out] int [] a1);
 
+       [DllImport ("libtest", EntryPoint="mono_test_marshal_out_array")]
+       public static extern int mono_test_marshal_out_array ([Out] [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] int [] a1, int n);
+
        [DllImport ("libtest", EntryPoint="mono_test_marshal_inout_nonblittable_array", CharSet = CharSet.Unicode)]
        public static extern int mono_test_marshal_inout_nonblittable_array ([In, Out] char [] a1);
        
@@ -148,6 +183,15 @@ public class Tests {
        [DllImport ("libtest", EntryPoint="mono_test_marshal_struct2_2")]
        public static extern int mono_test_marshal_struct2_2 (int i, int j, int k, SimpleStruct2 ss);
 
+       [DllImport ("libtest", EntryPoint="mono_test_marshal_byref_struct")]
+       public static extern int mono_test_marshal_byref_struct (ref SimpleStruct ss, bool a, bool b, bool c, String d);
+
+       [DllImport ("libtest", EntryPoint="mono_test_marshal_byref_struct")]
+       public static extern int mono_test_marshal_byref_struct_in ([In] ref SimpleStruct ss, bool a, bool b, bool c, String d);
+
+       [DllImport ("libtest", EntryPoint="mono_test_marshal_byref_struct")]
+       public static extern int mono_test_marshal_byref_struct_inout ([In, Out] ref SimpleStruct ss, bool a, bool b, bool c, String d);
+
        [DllImport ("libtest", EntryPoint="mono_test_marshal_point")]
        public static extern int mono_test_marshal_point (Point p);
 
@@ -157,6 +201,12 @@ public class Tests {
        [DllImport ("libtest", EntryPoint="mono_test_empty_struct")]
        public static extern int mono_test_empty_struct (int a, EmptyStruct es, int b);
 
+       [DllImport ("libtest", EntryPoint="mono_test_marshal_lpstruct")]
+       public static extern int mono_test_marshal_lpstruct ([In, MarshalAs(UnmanagedType.LPStruct)] SimpleStruct ss);
+
+       [DllImport ("libtest", EntryPoint="mono_test_marshal_lpstruct_blittable")]
+       public static extern int mono_test_marshal_lpstruct_blittable ([In, MarshalAs(UnmanagedType.LPStruct)] Point p);
+
        [DllImport ("libtest", EntryPoint="mono_test_marshal_struct_array")]
        public static extern int mono_test_marshal_struct_array (SimpleStruct2[] ss);
 
@@ -173,7 +223,7 @@ public class Tests {
        public static extern int mono_test_marshal_delegate (SimpleDelegate d);
 
        [DllImport ("libtest", EntryPoint="mono_test_marshal_delegate_struct")]
-       public static extern int mono_test_marshal_delegate_struct (DelegateStruct d);
+       public static extern DelegateStruct mono_test_marshal_delegate_struct (DelegateStruct d);
 
        [DllImport ("libtest", EntryPoint="mono_test_marshal_return_delegate")]
        public static extern SimpleDelegate mono_test_marshal_return_delegate (SimpleDelegate d);
@@ -196,17 +246,34 @@ public class Tests {
        [DllImport ("libtest", EntryPoint="mono_test_asany", CharSet=CharSet.Unicode)]
        public static extern int mono_test_asany_unicode ([MarshalAs (UnmanagedType.AsAny)] object o, int what);
 
+       [DllImport("libtest", EntryPoint="mono_test_marshal_asany_inout")]
+       static extern void mono_test_asany_in ([MarshalAs(UnmanagedType.AsAny)][In] object obj); 
+
+       [DllImport("libtest", EntryPoint="mono_test_marshal_asany_inout")]
+       static extern void mono_test_asany_out ([MarshalAs(UnmanagedType.AsAny)][Out] object obj); 
+       [DllImport("libtest", EntryPoint="mono_test_marshal_asany_inout")]
+       static extern void mono_test_asany_inout ([MarshalAs(UnmanagedType.AsAny)][In, Out] object obj); 
+
        [DllImport ("libtest")]
         static extern int class_marshal_test0 (SimpleObj obj);
 
        [DllImport ("libtest")]
         static extern void class_marshal_test1 (out SimpleObj obj);
+
+       [DllImport ("libtest")]
+        static extern int class_marshal_test4 (SimpleObj obj);
        
        [DllImport ("libtest")]
-        static extern int class_marshal_test2 (ref SimpleObj obj);
+        static extern int string_marshal_test0 (string str);
 
        [DllImport ("libtest")]
-        static extern int class_marshal_test4 (SimpleObj obj);
+        static extern void string_marshal_test1 (out string str);
+
+       [DllImport ("libtest")]
+        static extern int string_marshal_test2 (ref string str);
+
+       [DllImport ("libtest")]
+        static extern int string_marshal_test3 (string str);
 
        public delegate int SimpleDelegate (int a);
 
@@ -214,12 +281,12 @@ public class Tests {
                return TestDriver.RunTests (typeof (Tests), args);
        }
 
-       static int test_0_marshal_char () {
+       public static int test_0_marshal_char () {
                return mono_test_marshal_char ('a');
        }
 
-       static int test_0_marshal_char_array () {
-               // char[] is implicitly marshalled as [Out]
+       public static int test_0_marshal_char_array () {
+               // a unicode char[] is implicitly marshalled as [Out]
                char[] buf = new char [32];
                mono_test_marshal_char_array (buf);
                string s = new string (buf);
@@ -229,7 +296,7 @@ public class Tests {
                        return 1;
        }
 
-       static int test_1225_marshal_array () {
+       public static int test_1225_marshal_array () {
                int [] a1 = new int [50];
                for (int i = 0; i < 50; i++)
                        a1 [i] = i;
@@ -237,7 +304,7 @@ public class Tests {
                return mono_test_marshal_array (a1);
        }
 
-       static int test_1225_marshal_inout_array () {
+       public static int test_1225_marshal_inout_array () {
                int [] a1 = new int [50];
                for (int i = 0; i < 50; i++)
                        a1 [i] = i;
@@ -253,7 +320,21 @@ public class Tests {
                return res;
        }
 
-       static int test_0_marshal_inout_nonblittable_array () {
+       public static int test_0_marshal_out_array () {
+               int [] a1 = new int [50];
+
+               int res = mono_test_marshal_out_array (a1, 0);
+
+               for (int i = 0; i < 50; i++)
+                       if (a1 [i] != i) {
+                               Console.WriteLine ("X: " + i + " " + a1 [i]);
+                               return 2;
+                       }
+
+               return 0;
+       }
+
+       public static int test_0_marshal_inout_nonblittable_array () {
                char [] a1 = new char [10];
                for (int i = 0; i < 10; i++)
                        a1 [i] = "Hello, World" [i];
@@ -267,7 +348,7 @@ public class Tests {
                return res;
        }
 
-       static int test_0_marshal_struct () {
+       public static int test_0_marshal_struct () {
                SimpleStruct ss = new  SimpleStruct ();
                ss.b = true;
                ss.d = "TEST";
@@ -275,7 +356,7 @@ public class Tests {
                return mono_test_marshal_struct (ss);
        }
 
-       static int test_0_marshal_struct2 () {
+       public static int test_0_marshal_struct2 () {
                SimpleStruct2 ss2 = new  SimpleStruct2 ();
                ss2.b = true;
                ss2.d = "TEST";
@@ -287,7 +368,7 @@ public class Tests {
                return mono_test_marshal_struct2 (ss2);
        }
 
-       static int test_0_marshal_struct3 () {
+       public static int test_0_marshal_struct3 () {
                SimpleStruct2 ss2 = new  SimpleStruct2 ();
                ss2.b = true;
                ss2.d = "TEST";
@@ -299,7 +380,7 @@ public class Tests {
                return mono_test_marshal_struct2_2 (10, 11, 12, ss2);
        }
 
-       static int test_0_marshal_empty_struct () {
+       public static int test_0_marshal_empty_struct () {
                EmptyStruct es = new EmptyStruct ();
 
                if (mono_test_empty_struct (1, es, 2) != 0)
@@ -308,7 +389,23 @@ public class Tests {
                return 0;
        }
 
-       static int test_0_marshal_struct_array () {
+       public static int test_0_marshal_lpstruct () {
+               SimpleStruct ss = new  SimpleStruct ();
+               ss.b = true;
+               ss.d = "TEST";
+               
+               return mono_test_marshal_lpstruct (ss);
+       }
+
+       public static int test_0_marshal_lpstruct_blittable () {
+               Point p = new Point ();
+               p.x = 1.0;
+               p.y = 2.0;
+               
+               return mono_test_marshal_lpstruct_blittable (p);
+       }
+
+       public static int test_0_marshal_struct_array () {
                SimpleStruct2[] ss_arr = new SimpleStruct2 [2];
 
                SimpleStruct2 ss2 = new SimpleStruct2 ();
@@ -333,7 +430,7 @@ public class Tests {
                return mono_test_marshal_struct_array (ss_arr);
        }
 
-       static int test_105_marshal_long_align_struct_array () {
+       public static int test_105_marshal_long_align_struct_array () {
                LongAlignStruct[] ss_arr = new LongAlignStruct [2];
 
                LongAlignStruct ss = new LongAlignStruct ();
@@ -353,7 +450,7 @@ public class Tests {
        }
 
        /* Test classes as arguments and return values */
-       static int test_0_marshal_class () {
+       public static int test_0_marshal_class () {
                SimpleClass ss = new  SimpleClass ();
                ss.b = true;
                ss.d = "TEST";
@@ -378,7 +475,7 @@ public class Tests {
                return 0;
        }
 
-       static int test_0_marshal_byref_class () {
+       public static int test_0_marshal_byref_class () {
                SimpleClass ss = new  SimpleClass ();
                ss.b = true;
                ss.d = "TEST";
@@ -394,13 +491,13 @@ public class Tests {
                return 0;
        }
 
-       static int test_0_marshal_delegate () {
+       public static int test_0_marshal_delegate () {
                SimpleDelegate d = new SimpleDelegate (delegate_test);
 
                return mono_test_marshal_delegate (d);
        }
 
-       static int test_0_marshal_return_delegate () {
+       public static int test_0_marshal_return_delegate () {
                SimpleDelegate d = new SimpleDelegate (delegate_test);
 
                SimpleDelegate d2 = mono_test_marshal_return_delegate (d);
@@ -408,17 +505,74 @@ public class Tests {
                return d2 (2);
        }
 
-       static int test_0_marshal_delegate_struct () {
+       public static int test_0_marshal_delegate_struct () {
                DelegateStruct s = new DelegateStruct ();
 
                s.a = 2;
                s.del = new SimpleDelegate (delegate_test);
                s.del2 = new SimpleDelegate (delegate_test);
 
-               return mono_test_marshal_delegate_struct (s);
+               DelegateStruct res = mono_test_marshal_delegate_struct (s);
+
+               if (res.a != 0)
+                       return 1;
+               if (res.del (2) != 0)
+                       return 2;
+               if (res.del2 (2) != 0)
+                       return 3;
+
+               return 0;
+       }
+
+       public static int test_0_marshal_byref_struct () {
+               SimpleStruct s = new SimpleStruct ();
+               s.a = true;
+               s.b = false;
+               s.c = true;
+               s.d = "ABC";
+               s.d2 = "DEF";
+
+               int res = mono_test_marshal_byref_struct (ref s, true, false, true, "ABC");
+               if (res != 0)
+                       return 1;
+               if (s.a != false || s.b != true || s.c != false || s.d != "DEF")
+                       return 2;
+               return 0;
        }
 
-       static int test_0_marshal_point () {
+       public static int test_0_marshal_byref_struct_in () {
+               SimpleStruct s = new SimpleStruct ();
+               s.a = true;
+               s.b = false;
+               s.c = true;
+               s.d = "ABC";
+               s.d2 = "DEF";
+
+               int res = mono_test_marshal_byref_struct_in (ref s, true, false, true, "ABC");
+               if (res != 0)
+                       return 1;
+               if (s.a != true || s.b != false || s.c != true || s.d != "ABC")
+                       return 2;
+               return 0;
+       }
+
+       public static int test_0_marshal_byref_struct_inout () {
+               SimpleStruct s = new SimpleStruct ();
+               s.a = true;
+               s.b = false;
+               s.c = true;
+               s.d = "ABC";
+               s.d2 = "DEF";
+
+               int res = mono_test_marshal_byref_struct_inout (ref s, true, false, true, "ABC");
+               if (res != 0)
+                       return 1;
+               if (s.a != false || s.b != true || s.c != false || s.d != "DEF")
+                       return 2;
+               return 0;
+       }
+
+       public static int test_0_marshal_point () {
                Point pt = new Point();
                pt.x = 1.25;
                pt.y = 3.5;
@@ -426,7 +580,7 @@ public class Tests {
                return mono_test_marshal_point(pt);
        }
 
-       static int test_0_marshal_mixed_point () {
+       public static int test_0_marshal_mixed_point () {
                MixedPoint mpt = new MixedPoint();
                mpt.x = 5;
                mpt.y = 6.75;
@@ -434,7 +588,7 @@ public class Tests {
                return mono_test_marshal_mixed_point(mpt);
        }
 
-       static int test_0_marshal_bool_byref () {
+       public static int test_0_marshal_bool_byref () {
                bool b = true;
                if (mono_test_marshal_bool_byref (99, ref b, 100) != 1)
                        return 1;
@@ -447,7 +601,7 @@ public class Tests {
                return 0;
        }
 
-       static int test_0_return_vtype () {
+       public static int test_0_return_vtype () {
                SimpleStruct ss = mono_test_return_vtype (new IntPtr (5));
 
                if (!ss.a && ss.b && !ss.c && ss.d == "TEST" && ss.d2 == "TEST2")
@@ -456,7 +610,7 @@ public class Tests {
                return 1;
        }
 
-       static int test_0_marshal_stringbuilder () {
+       public static int test_0_marshal_stringbuilder () {
                StringBuilder sb = new StringBuilder(255);
                sb.Append ("ABCD");
                mono_test_marshal_stringbuilder (sb, sb.Capacity);
@@ -468,7 +622,7 @@ public class Tests {
                return 0;
        }
 
-       static int test_0_marshal_stringbuilder_unicode () {
+       public static int test_0_marshal_stringbuilder_unicode () {
                StringBuilder sb = new StringBuilder(255);
                mono_test_marshal_stringbuilder_unicode (sb, sb.Capacity);
                String res = sb.ToString();
@@ -479,19 +633,19 @@ public class Tests {
                return 0;
        }
 
-       static int test_0_marshal_empty_string_array () {
+       public static int test_0_marshal_empty_string_array () {
                return mono_test_marshal_empty_string_array (null);
        }
 
-       static int test_0_marshal_string_array () {
+       public static int test_0_marshal_string_array () {
                return mono_test_marshal_string_array (new String [] { "ABC", "DEF" });
        }
 
-       static int test_0_marshal_unicode_string_array () {
+       public static int test_0_marshal_unicode_string_array () {
                return mono_test_marshal_unicode_string_array (new String [] { "ABC", "DEF" }, new String [] { "ABC", "DEF" });
        }
 
-       static int test_0_marshal_stringbuilder_array () {
+       public static int test_0_marshal_stringbuilder_array () {
                StringBuilder sb1 = new StringBuilder ("ABC");
                StringBuilder sb2 = new StringBuilder ("DEF");
 
@@ -505,7 +659,7 @@ public class Tests {
                return 0;
        }
 
-       static int test_0_last_error () {
+       public static int test_0_last_error () {
                mono_test_last_error (5);
                if (Marshal.GetLastWin32Error () == 5)
                        return 0;
@@ -513,7 +667,7 @@ public class Tests {
                        return 1;
        }
 
-       static int test_0_library_not_found () {
+       public static int test_0_library_not_found () {
 
                try {
                        mono_entry_point_not_found ();
@@ -525,7 +679,7 @@ public class Tests {
                return 0;
        }
 
-       static int test_0_entry_point_not_found () {
+       public static int test_0_entry_point_not_found () {
 
                try {
                        mono_library_not_found ();
@@ -538,7 +692,7 @@ public class Tests {
        }
 
        /* Check that the runtime trims .dll from the library name */
-       static int test_0_trim_dll_from_name () {
+       public static int test_0_trim_dll_from_name () {
 
                mono_test_marshal_char_2 ('A');
 
@@ -546,7 +700,7 @@ public class Tests {
        }
 
        /* Check that the runtime adds lib to to the library name */
-       static int test_0_add_lib_to_name () {
+       public static int test_0_add_lib_to_name () {
 
                mono_test_marshal_char_3 ('A');
 
@@ -557,7 +711,7 @@ public class Tests {
                public int i;
        }
 
-       static int test_0_asany () {
+       public static int test_0_asany () {
                if (mono_test_asany (5, 1) != 0)
                        return 1;
 
@@ -597,6 +751,71 @@ public class Tests {
                return 0;
        }
 
+       /* AsAny marshalling + [In, Out] */
+
+       public static int test_0_asany_in () {
+               // Struct
+               AsAnyStruct str = new AsAnyStruct(1,2,3, "ABC");
+               mono_test_asany_in (str);
+
+               // Formatted Class
+               AsAnyClass cls = new AsAnyClass(1,2,3, "ABC");
+               mono_test_asany_in (cls);
+               if ((cls.i != 1) || (cls.j != 2) || (cls.k != 3))
+                       return 1;
+
+               // Boxed Struct
+               object obj = new AsAnyStruct(1,2,3, "ABC");
+               mono_test_asany_in (obj);
+               str = (AsAnyStruct)obj;
+               if ((str.i != 1) || (str.j != 2) || (str.k != 3))
+                       return 2;
+
+               return 0;
+       }
+
+       public static int test_0_asany_out () {
+               // Struct
+               AsAnyStruct str = new AsAnyStruct(1,2,3, "ABC");
+               mono_test_asany_out (str);
+
+               // Formatted Class
+               AsAnyClass cls = new AsAnyClass(1,2,3, "ABC");
+               mono_test_asany_out (cls);
+               if ((cls.i != 10) || (cls.j != 20) || (cls.k != 30))
+                       return 1;
+
+               // Boxed Struct
+               object obj = new AsAnyStruct(1,2,3, "ABC");
+               mono_test_asany_out (obj);
+               str = (AsAnyStruct)obj;
+               if ((str.i != 10) || (str.j != 20) || (str.k != 30))
+                       return 2;
+
+               return 0;
+       }
+
+       public static int test_0_asany_inout () {
+               // Struct
+               AsAnyStruct str = new AsAnyStruct(1,2,3, "ABC");
+               mono_test_asany_inout (str);
+
+               // Formatted Class
+               AsAnyClass cls = new AsAnyClass(1,2,3, "ABC");
+               mono_test_asany_inout (cls);
+               if ((cls.i != 10) || (cls.j != 20) || (cls.k != 30))
+                       return 1;
+
+               // Boxed Struct
+               object obj = new AsAnyStruct(1,2,3, "ABC");
+               mono_test_asany_inout (obj);
+               str = (AsAnyStruct)obj;
+               if ((str.i != 10) || (str.j != 20) || (str.k != 30))
+                       return 2;
+
+               return 0;
+       }
+
        /* Byref String Array */
 
        [DllImport ("libtest", EntryPoint="mono_test_marshal_byref_string_array")]
@@ -708,6 +927,50 @@ public class Tests {
                return (s2.d1 == 6.0 && s2.d2 == -4.0) ? 0 : 1;
        }
 
+       /*
+        * IA64 struct tests
+        */
+
+       /* Test 5: Float HFA */
+
+       [StructLayout(LayoutKind.Sequential)]
+       public struct TestStruct5 {
+               public float d1, d2;
+       }
+       
+       [DllImport ("libtest", EntryPoint="mono_test_marshal_ia64_pass_return_struct5")]
+       public static extern TestStruct5 mono_test_marshal_ia64_pass_return_struct5 (double d1, double d2, TestStruct5 s, double f3, double f4);
+
+       public static int test_0_ia64_struct5 () {
+               TestStruct5 s = new TestStruct5 ();
+               s.d1 = 5.0f;
+               s.d2 = -5.0f;
+
+               TestStruct5 s2 = mono_test_marshal_ia64_pass_return_struct5 (1.0, 2.0, s, 3.0, 4.0);
+
+               return (s2.d1 == 8.0 && s2.d2 == 2.0) ? 0 : 1;
+       }
+
+       /* Test 6: Double HFA */
+
+       [StructLayout(LayoutKind.Sequential)]
+       public struct TestStruct6 {
+               public double d1, d2;
+       }
+       
+       [DllImport ("libtest", EntryPoint="mono_test_marshal_ia64_pass_return_struct6")]
+       public static extern TestStruct6 mono_test_marshal_ia64_pass_return_struct6 (double d1, double d2, TestStruct6 s, double f3, double f4);
+
+       public static int test_0_ia64_struct6 () {
+               TestStruct6 s = new TestStruct6 ();
+               s.d1 = 6.0;
+               s.d2 = -6.0;
+
+               TestStruct6 s2 = mono_test_marshal_ia64_pass_return_struct6 (1.0, 2.0, s, 3.0, 4.0);
+
+               return (s2.d1 == 9.0 && s2.d2 == 1.0) ? 0 : 1;
+       }
+       
        /* Blittable class */
        [DllImport("libtest")]
        private static extern VectorList TestVectorList (VectorList vl);
@@ -727,7 +990,7 @@ public class Tests {
                return 0;
        }
 
-       static int test_0_marshal_byval_class () {
+       public static int test_0_marshal_byval_class () {
                SimpleObj obj0 = new SimpleObj ();
                obj0.str = "T1";
                obj0.i = 4;
@@ -738,14 +1001,14 @@ public class Tests {
                return 0;
        }
 
-       static int test_0_marshal_byval_class_null () {
+       public static int test_0_marshal_byval_class_null () {
                if (class_marshal_test4 (null) != 0)
                        return 1;
 
                return 0;
        }
 
-       static int test_0_marshal_out_class () {
+       public static int test_0_marshal_out_class () {
                SimpleObj obj1;
 
                class_marshal_test1 (out obj1);
@@ -759,11 +1022,213 @@ public class Tests {
                return 0;
        }
 
+       public static int test_0_marshal_string () {
+               return string_marshal_test0 ("TEST0");
+       }
+
+       public static int test_0_marshal_out_string () {
+               string res;
+               
+               string_marshal_test1 (out res);
+
+               if (res != "TEST1")
+                       return 1;
+
+               return 0;
+       }
+
+       public static int test_0_marshal_byref_string () {
+               string res = "TEST1";
+
+               return string_marshal_test2 (ref res);
+       }
+
+       public static int test_0_marshal_null_string () {
+               return string_marshal_test3 (null);
+       }
+
        [DllImport ("libtest", EntryPoint="mono_test_stdcall_name_mangling", CallingConvention=CallingConvention.StdCall)]
        public static extern int mono_test_stdcall_name_mangling (int a, int b, int c);
 
-       static int test_0_stdcall_name_mangling () {
+       public static int test_0_stdcall_name_mangling () {
                return mono_test_stdcall_name_mangling (0, 1, 2) == 3 ? 0 : 1;
        }
+
+       /*
+        * Pointers to structures can not be passed
+        */
+
+       public struct CharInfo {
+               public char Character;
+               public short Attributes;
+       }
+
+       [DllImport ("libtest", EntryPoint="mono_test_marshal_struct")]
+       public static unsafe extern int mono_test_marshal_ptr_to_struct (CharInfo *ptr);
+
+       public static unsafe int test_0_marshal_ptr_to_struct () {
+               CharInfo [] buffer = new CharInfo [1];
+               fixed (CharInfo *ptr = &buffer [0]) {
+                       try {
+                               mono_test_marshal_ptr_to_struct (ptr);
+                               return 1;
+                       }
+                       catch (MarshalDirectiveException) {
+                               return 0;
+                       }
+               }
+               return 1;
+       }
+
+       /*
+        * LPWStr marshalling
+        */
+
+       [DllImport("libtest", EntryPoint="test_lpwstr_marshal")]
+       [return: MarshalAs(UnmanagedType.LPWStr)]
+       private static extern string mono_test_marshal_lpwstr_marshal(
+               [MarshalAs(UnmanagedType.LPWStr)] string s,
+               int length );
+
+       [DllImport("libtest", EntryPoint="test_lpwstr_marshal", CharSet=CharSet.Unicode)]
+       private static extern string mono_test_marshal_lpwstr_marshal2(
+               string s,
+               int length );
+
+       public static int test_0_pass_return_lwpstr () {
+               string s = "ABC";
+               
+               string res = mono_test_marshal_lpwstr_marshal (s, s.Length);
+
+               if (res != "ABC")
+                       return 1;
+
+               string res2 = mono_test_marshal_lpwstr_marshal2 (s, s.Length);
+
+               if (res2 != "ABC")
+                       return 2;
+               
+               return 0;               
+       }
+
+       /*
+        * Byref bool marshalling
+        */
+
+       [DllImport("libtest")]
+       extern static int marshal_test_ref_bool
+       (
+               int i, 
+               [MarshalAs(UnmanagedType.I1)] ref bool b1, 
+               [MarshalAs(UnmanagedType.VariantBool)] ref bool b2, 
+               ref bool b3
+       );
+
+       public static int test_0_pass_byref_bool () {
+               for (int i = 0; i < 8; i++)
+               {
+                       bool b1 = (i & 4) != 0;
+                       bool b2 = (i & 2) != 0;
+                       bool b3 = (i & 1) != 0;
+                       bool orig_b1 = b1, orig_b2 = b2, orig_b3 = b3;
+                       if (marshal_test_ref_bool(i, ref b1, ref b2, ref b3) != 0)
+                               return 4 * i + 1;
+                       if (b1 != !orig_b1)
+                               return 4 * i + 2;
+                       if (b2 != !orig_b2)
+                               return 4 * i + 3;
+                       if (b3 != !orig_b3)
+                               return 4 * i + 4;
+               }
+
+               return 0;
+       }
+
+       /*
+        * Bool struct field marshalling
+        */
+
+       struct BoolStruct
+       {
+               public int i;
+               [MarshalAs(UnmanagedType.I1)] public bool b1;
+               [MarshalAs(UnmanagedType.VariantBool)] public bool b2;
+               public bool b3;
+       }
+
+       [DllImport("libtest")]
+       extern static int marshal_test_bool_struct(ref BoolStruct s);
+
+       public static int test_0_pass_bool_in_struct () {
+               for (int i = 0; i < 8; i++)
+               {
+                       BoolStruct s = new BoolStruct();
+                       s.i = i;
+                       s.b1 = (i & 4) != 0;
+                       s.b2 = (i & 2) != 0;
+                       s.b3 = (i & 1) != 0;
+                       BoolStruct orig = s;
+                       if (marshal_test_bool_struct(ref s) != 0)
+                               return 4 * i + 33;
+                       if (s.b1 != !orig.b1)
+                               return 4 * i + 34;
+                       if (s.b2 != !orig.b2)
+                               return 4 * i + 35;
+                       if (s.b3 != !orig.b3)
+                               return 4 * i + 36;
+               }
+
+               return 0;
+       }
+
+       /*
+        * Invoking pinvoke methods through delegates
+        */
+
+       delegate int MyDelegate (string name);
+
+       [DllImport ("libtest", EntryPoint="mono_test_puts_static")]
+       public static extern int puts_static (string name);
+
+       public static int test_0_invoke_pinvoke_through_delegate () {
+               puts_static ("A simple Test for PInvoke 1");
+
+               MyDelegate d = new MyDelegate (puts_static);
+               d ("A simple Test for PInvoke 2");
+
+               object [] args = {"A simple Test for PInvoke 3"};
+               d.DynamicInvoke (args);
+
+               return 0;
+       }
+
+       /*
+        * Missing virtual pinvoke methods
+        */
+
+       public class T {
+
+               public virtual object MyClone ()
+               {
+                       return null;
+               }
+       }
+
+       public class T2 : T {
+               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               public override extern object MyClone ();
+       }
+
+       public static int test_0_missing_virtual_pinvoke_method () {
+               T2 t = new T2 ();
+
+               try {
+                       t.MyClone ();
+               } catch (Exception ex) {
+                       return 0;
+               }
+               
+               return 1;
+       }
 }