X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Ftests%2Fpinvoke3.cs;h=ae64d16e090d7af29dd027197a083e92bb2d7845;hb=012f8610237dfe44034c9d8daea0b90fac75ca9f;hp=c9821b1704fbb0e79e9b802bf9d029eae322079c;hpb=00e065484e866f3a0349c882f804c4a79a13ee5c;p=mono.git diff --git a/mono/tests/pinvoke3.cs b/mono/tests/pinvoke3.cs index c9821b1704f..c1354ce9b54 100644 --- a/mono/tests/pinvoke3.cs +++ b/mono/tests/pinvoke3.cs @@ -5,7 +5,9 @@ // using System; +using System.Text; using System.Runtime.InteropServices; +using System.Threading; public class Tests { @@ -64,6 +66,19 @@ public class Tests { return 0; } + public static int delegate_test_struct_in (int a, [In] ref SimpleStruct ss, int b) + { + if (a == 1 && b == 2 && ss.a && !ss.b && ss.c && ss.d == "TEST2") { + ss.a = true; + ss.b = true; + ss.c = true; + ss.d = "TEST3"; + return 0; + } + + return 1; + } + public static SimpleClass delegate_test_class (SimpleClass ss) { if (ss == null) @@ -119,13 +134,26 @@ public class Tests { return s == "ABC" ? 0 : 1; } + public static int delegate_test_string_builder_marshalling (StringBuilder s) + { + if (s == null) + return 2; + else + return s.ToString () == "ABC" ? 0 : 1; + } + [DllImport ("libtest", EntryPoint="mono_test_ref_vtype")] public static extern int mono_test_ref_vtype (int a, ref SimpleStruct ss, int b, TestDelegate d); public delegate int OutStructDelegate (int a, out SimpleStruct ss, int b); + public delegate int InStructDelegate (int a, [In] ref SimpleStruct ss, int b); + [DllImport ("libtest", EntryPoint="mono_test_marshal_out_struct")] public static extern int mono_test_marshal_out_struct (int a, out SimpleStruct ss, int b, OutStructDelegate d); + + [DllImport ("libtest", EntryPoint="mono_test_marshal_in_struct")] + public static extern int mono_test_marshal_in_struct (int a, ref SimpleStruct ss, int b, InStructDelegate d); [DllImport ("libtest", EntryPoint="mono_test_marshal_delegate2")] public static extern int mono_test_marshal_delegate2 (SimpleDelegate2 d); @@ -151,12 +179,26 @@ public class Tests { [DllImport ("libtest", EntryPoint="mono_test_marshal_delegate10")] public static extern int mono_test_marshal_delegate10 (SimpleDelegate9 d); + [DllImport ("libtest", EntryPoint="mono_test_marshal_delegate8")] + public static extern int mono_test_marshal_delegate11 (SimpleDelegate11 d, string s); + [DllImport ("libtest", EntryPoint="mono_test_marshal_primitive_byref_delegate")] public static extern int mono_test_marshal_primitive_byref_delegate (PrimitiveByrefDelegate d); [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); + + [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); @@ -173,10 +215,16 @@ public class Tests { public delegate int SimpleDelegate9 (return_int_delegate del); + public delegate int SimpleDelegate11 (StringBuilder s1); + public delegate int PrimitiveByrefDelegate (ref int i); public delegate return_int_delegate ReturnDelegateDelegate (); + public delegate int DelegateByrefDelegate (ref return_int_delegate del); + + public delegate int VirtualDelegate (int i); + public static int Main () { return TestDriver.RunTests (typeof (Tests)); } @@ -213,6 +261,14 @@ public class Tests { return mono_test_marshal_out_struct (1, out ss, 2, d); } + /* Test structures as in arguments of delegates */ + public static int test_0_marshal_in_struct_delegate () { + SimpleStruct ss = new SimpleStruct () { a = true, b = false, c = true, d = "TEST2" }; + InStructDelegate d = new InStructDelegate (delegate_test_struct_in); + + return mono_test_marshal_in_struct (1, ref ss, 2, d); + } + /* Test classes as arguments and return values of delegates */ public static int test_0_marshal_class_delegate () { SimpleDelegate4 d = new SimpleDelegate4 (delegate_test_class); @@ -241,6 +297,16 @@ public class Tests { return mono_test_marshal_delegate8 (d, "ABC"); } + /* Test string builder marshalling with delegates */ + public static int test_0_marshal_string_builder_delegate () { + SimpleDelegate11 d = new SimpleDelegate11 (delegate_test_string_builder_marshalling); + + if (mono_test_marshal_delegate11 (d, null) != 2) + return 2; + + return mono_test_marshal_delegate11 (d, "ABC"); + } + /* Test that the delegate wrapper correctly catches null byref arguments */ public static int test_0_marshal_byref_class_delegate_null () { SimpleDelegate5 d = new SimpleDelegate5 (delegate_test_class_byref); @@ -282,6 +348,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); @@ -666,6 +746,21 @@ public class Tests { return mono_test_marshal_array_delegate1 (null, 0, new ArrayDelegate1 (array_delegate2)); } + public delegate int ArrayDelegateBlittable (int i, string j, + [In, MarshalAs(UnmanagedType.LPArray, + ArraySubType=UnmanagedType.LPStr, SizeParamIndex=0)] int[] arr); + + [DllImport ("libtest", EntryPoint="mono_test_marshal_array_delegate")] + public static extern int mono_test_marshal_array_delegate1 (string[] arr, int len, ArrayDelegateBlittable d); + + public static int array_delegate_null_blittable (int i, string j, int[] arr) { + return (arr == null) ? 0 : 1; + } + + public static int test_0_marshal_array_delegate_null_blittable () { + return mono_test_marshal_array_delegate1 (null, 0, new ArrayDelegateBlittable (array_delegate_null_blittable)); + } + public delegate int ArrayDelegate3 (int i, string j, [In, MarshalAs(UnmanagedType.LPArray, @@ -710,6 +805,49 @@ public class Tests { } } + public delegate int ArrayDelegate4_2 (int i, + string j, + string[] arr); + + [DllImport ("libtest", EntryPoint="mono_test_marshal_array_delegate")] + public static extern int mono_test_marshal_array_delegate4_2 (string[] arr, int len, ArrayDelegate4_2 d); + + public static int array_delegate4_2 (int i, string j, string[] arr) { + return (arr == null) ? 0 : 1; + } + + public static int test_0_marshal_array_delegate_no_marshal_directive () { + try { + mono_test_marshal_array_delegate4_2 (null, 0, new ArrayDelegate4_2 (array_delegate4_2)); + return 1; + } + catch (MarshalDirectiveException) { + return 0; + } + } + + public delegate int ArrayDelegate4_3 (int i, + string j, + string[] arr); + + [DllImport ("libtest", EntryPoint="mono_test_marshal_array_delegate")] + public static extern int mono_test_marshal_array_delegate4_3 (string[] arr, int len, ArrayDelegate4_3 d); + + public int array_delegate4_3 (int i, string j, string[] arr) { + return (arr == null) ? 0 : 1; + } + + public static int test_0_marshal_array_delegate_no_marshal_directive_instance () { + try { + Tests t = new Tests (); + mono_test_marshal_array_delegate4_3 (null, 0, new ArrayDelegate4_3 (t.array_delegate4_3)); + return 1; + } + catch (MarshalDirectiveException) { + return 0; + } + } + public delegate int ArrayDelegate5 (int i, string j, [In, MarshalAs(UnmanagedType.LPArray, @@ -794,6 +932,30 @@ public class Tests { return mono_test_marshal_array_delegate8 (arr, 2, new ArrayDelegate8 (array_delegate8)); } + /* Array with size param of type long */ + + public delegate int ArrayDelegate8_2 (long i, + string j, + [In, MarshalAs(UnmanagedType.LPArray, + ArraySubType=UnmanagedType.LPStr, SizeParamIndex=0)] string[] arr); + + [DllImport ("libtest", EntryPoint="mono_test_marshal_array_delegate_long")] + public static extern int mono_test_marshal_array_delegate8_2 (string[] arr, long len, ArrayDelegate8_2 d); + + public static int array_delegate8_2 (long i, string j, string[] arr) { + if (arr.Length != 2) + return 1; + if ((arr [0] != "ABC") || (arr [1] != "DEF")) + return 2; + return 0; + } + + public static int test_0_marshal_array_delegate_long_param () { + string[] arr = new string [] { "ABC", "DEF" }; + return mono_test_marshal_array_delegate8_2 (arr, arr.Length, new ArrayDelegate8_2 (array_delegate8_2)); + } + + /* * [Out] blittable arrays */ @@ -873,6 +1035,23 @@ public class Tests { return mono_test_marshal_inout_byval_class_delegate (new InOutByvalClassDelegate (delegate_test_byval_class_inout)); } + /* + * Returning unicode strings + */ + [return: MarshalAs(UnmanagedType.LPWStr)] + public delegate string ReturnUnicodeStringDelegate([MarshalAs(UnmanagedType.LPWStr)] string message); + + [DllImport ("libtest", EntryPoint="mono_test_marshal_return_unicode_string_delegate")] + public static extern int mono_test_marshal_return_unicode_string_delegate (ReturnUnicodeStringDelegate d); + + public static String return_unicode_string_delegate (string message) { + return message; + } + + public static int test_0_marshal_return_unicode_string_delegate () { + return mono_test_marshal_return_unicode_string_delegate (new ReturnUnicodeStringDelegate (return_unicode_string_delegate)); + } + /* * Returning string arrays */ @@ -902,4 +1081,191 @@ public class Tests { return mono_test_marshal_return_string_array_delegate (new ReturnArrayDelegate (return_array_delegate_null)); } + /* + * Byref string marshalling + */ + public delegate int ByrefStringDelegate (ref string s); + + [DllImport ("libtest", EntryPoint="mono_test_marshal_byref_string_delegate")] + public static extern int mono_test_marshal_byref_string_delegate (ByrefStringDelegate d); + + public static int byref_string_delegate (ref string s) { + if (s != "ABC") + return 1; + + s = "DEF"; + + return 0; + } + + public static int test_0_marshal_byref_string_delegate () { + return mono_test_marshal_byref_string_delegate (new ByrefStringDelegate (byref_string_delegate)); + } + + /* + * Thread attach + */ + + public delegate int SimpleDelegate (int i); + + [DllImport ("libtest", EntryPoint="mono_test_marshal_thread_attach")] + public static extern int mono_test_marshal_thread_attach (SimpleDelegate d); + + public static int test_43_thread_attach () { + int res = mono_test_marshal_thread_attach (delegate (int i) { + if (!Thread.CurrentThread.IsBackground) + return 0; + return i + 1; + }); + return res; + } + + public struct LargeStruct { + public Int16 s; + public Int16 v; + public UInt32 p; + public UInt32 e; + public Int32 l; + public Int32 ll; + public UInt16 h; + public Int16 r; + public Int16 pp; + public Int32 hh; + public Int32 bn; + public Int32 dn; + public Int32 dr; + public Int32 sh; + public Int32 ra; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] + public Int32[] angle; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] + public Int32[] width; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] + public Int32[] edge; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3 * 1024)] + public byte[] echo; + } + + public delegate int LargeStructDelegate (ref LargeStruct s); + + [DllImport ("libtest", EntryPoint="mono_test_marshal_thread_attach_large_vt")] + public static extern int mono_test_marshal_thread_attach_large_vt (LargeStructDelegate d); + + public static int test_43_thread_attach_large_vt () { + int res = mono_test_marshal_thread_attach_large_vt (delegate (ref LargeStruct s) { + return 43; + }); + return res; + } + + class Worker { + volatile bool stop = false; + public void Stop () { + stop = true; + } + + public void Work () { + while (!stop) { + for (int i = 0; i < 100; i++) { + var a = new double[80000]; + Thread.Sleep (0); + } + GC.Collect (); + } + } + } + + public static int test_43_thread_attach_detach_contested () { + // Test plan: we want to create a race between the GC + // and native threads detaching. When a native thread + // calls a managed delegate, it's attached to the + // runtime by the wrapper. It is detached when the + // thread is destroyed and the TLS key destructor for + // MonoThreadInfo runs. That destructor wants to take + // the GC lock. So we create a lot of native threads + // while at the same time running a worker that + // allocates garbage and invokes the collector. + var w = new Worker (); + Thread t = new Thread(new ThreadStart (w.Work)); + t.Start (); + + for (int count = 0; count < 500; count++) { + int res = mono_test_marshal_thread_attach (delegate (int i) { + Thread.Sleep (0); + return i + 1; + }); + } + Thread.Sleep (1000); + w.Stop (); + t.Join (); + return 43; + + } + /* + * Appdomain save/restore + */ + static Func callback; + + [DllImport ("libtest", EntryPoint="mono_test_marshal_set_callback")] + public static extern int mono_test_marshal_set_callback (Func a); + + [DllImport ("libtest", EntryPoint="mono_test_marshal_call_callback")] + public static extern int mono_test_marshal_call_callback (); + + public static int test_0_appdomain_switch () { + // FIXME: The appdomain unload hangs + //return 0; + AppDomain ad = AppDomain.CreateDomain ("foo"); + var c = (CallbackClass)ad.CreateInstanceAndUnwrap ( + typeof (CallbackClass).Assembly.FullName, "Tests/CallbackClass"); + c.SetCallback (); + int domain_id = AppDomain.CurrentDomain.Id; + int new_id = mono_test_marshal_call_callback (); + int res = 0; + if (new_id == domain_id) + res = 1; + if (AppDomain.CurrentDomain.Id != domain_id) + res = 2; + AppDomain.Unload (ad); + return res; + } + + static int domain_callback () { + return AppDomain.CurrentDomain.Id; + } + + class CallbackClass : MarshalByRefObject { + public int SetCallback () { + mono_test_marshal_set_callback (domain_callback); + return 0; + } + } + + class Base { + public VirtualDelegate get_del () { + return delegate_test; + } + + public virtual int delegate_test (int i) { + return i; + } + } + + class Derived : Base { + public override int delegate_test (int i) { + return i + 1; + } + } + + public static int test_43_virtual () { + Base b = new Derived (); + + 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)); + } }