X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Ftests%2Fpinvoke2.cs;h=826b91e1f8f7d4b38f48a062cf624f18b42ed516;hb=989100d5f0a5e7f4f62f2580b43921444d45ce60;hp=3d6bef72422a589034cfa2db21bd610fabace651;hpb=eb1a44caa88a60a16e5d782eddcc9fc30647521d;p=mono.git diff --git a/mono/tests/pinvoke2.cs b/mono/tests/pinvoke2.cs index 3d6bef72422..826b91e1f8f 100644 --- a/mono/tests/pinvoke2.cs +++ b/mono/tests/pinvoke2.cs @@ -1,7 +1,12 @@ +// +// Copyright 2011 Xamarin Inc (http://www.xamarin.com). +// + using System; using System.Text; using System.Runtime.InteropServices; using System.Runtime.CompilerServices; +using System.Reflection.Emit; public class Tests { @@ -30,6 +35,16 @@ public class Tests { public string d2; } + [StructLayout (LayoutKind.Sequential)] + public struct SimpleStructGen { + public bool a; + public bool b; + public bool c; + public string d; + [MarshalAs(UnmanagedType.LPWStr)] + public string d2; + } + [StructLayout (LayoutKind.Sequential)] public struct SimpleStruct2 { public bool a; @@ -52,6 +67,8 @@ public class Tests { public SimpleDelegate del; [MarshalAs(UnmanagedType.FunctionPtr)] public SimpleDelegate del2; + [MarshalAs(UnmanagedType.FunctionPtr)] + public SimpleDelegate del3; } /* sparcv9 has complex conventions when passing structs with doubles in them @@ -201,6 +218,9 @@ public class Tests { [DllImport ("libtest", EntryPoint="mono_test_marshal_struct")] public static extern int mono_test_marshal_struct (SimpleStruct ss); + + [DllImport ("libtest", EntryPoint="mono_test_marshal_struct")] + public static extern int mono_test_marshal_struct_gen (SimpleStructGen ss); [DllImport ("libtest", EntryPoint="mono_test_marshal_struct2")] public static extern int mono_test_marshal_struct2 (SimpleStruct2 ss); @@ -265,6 +285,12 @@ public class Tests { [DllImport ("libtest", EntryPoint="mono_test_marshal_stringbuilder_unicode", CharSet=CharSet.Unicode)] public static extern void mono_test_marshal_stringbuilder_unicode (StringBuilder sb, int len); + [DllImport ("libtest", EntryPoint="mono_test_marshal_stringbuilder_out")] + public static extern void mono_test_marshal_stringbuilder_out (out StringBuilder sb); + + [DllImport ("libtest", EntryPoint="mono_test_marshal_stringbuilder_out_unicode", CharSet=CharSet.Unicode)] + public static extern void mono_test_marshal_stringbuilder_out_unicode (out StringBuilder sb); + [DllImport ("libtest", EntryPoint="mono_test_last_error", SetLastError=true)] public static extern void mono_test_last_error (int err); @@ -384,6 +410,14 @@ public class Tests { return mono_test_marshal_struct (ss); } + public static int test_0_marshal_struct_gen () { + SimpleStructGen ss = new SimpleStructGen (); + ss.b = true; + ss.d = "TEST"; + + return mono_test_marshal_struct_gen (ss); + } + public static int test_0_marshal_struct2 () { SimpleStruct2 ss2 = new SimpleStruct2 (); ss2.b = true; @@ -533,6 +567,19 @@ public class Tests { return mono_test_marshal_delegate (d); } + /* Static delegates closed over their first argument */ + public static int closed_delegate (Tests t, int a) { + return t.int_field + a; + } + + public static int test_34_marshal_closed_static_delegate () { + Tests t = new Tests (); + t.int_field = 32; + SimpleDelegate d = (SimpleDelegate)Delegate.CreateDelegate (typeof (SimpleDelegate), t, typeof (Tests).GetMethod ("closed_delegate")); + + return mono_test_marshal_delegate (d); + } + public static int test_0_marshal_return_delegate () { SimpleDelegate d = new SimpleDelegate (delegate_test); @@ -547,6 +594,7 @@ public class Tests { s.a = 2; s.del = new SimpleDelegate (delegate_test); s.del2 = new SimpleDelegate (delegate_test); + s.del3 = null; DelegateStruct res = mono_test_marshal_delegate_struct (s); @@ -556,10 +604,23 @@ public class Tests { return 2; if (res.del2 (2) != 0) return 3; + if (res.del3 != null) + return 4; return 0; } + [DllImport ("libtest", EntryPoint="mono_test_marshal_out_delegate")] + public static extern int mono_test_marshal_out_delegate (out SimpleDelegate d); + + public static int test_3_marshal_out_delegate () { + SimpleDelegate d = null; + + mono_test_marshal_out_delegate (out d); + + return d (2); + } + public static int test_0_marshal_byref_struct () { SimpleStruct s = new SimpleStruct (); s.a = true; @@ -737,6 +798,24 @@ public class Tests { return 0; } + public static int test_0_marshal_stringbuilder_out () { + StringBuilder sb; + mono_test_marshal_stringbuilder_out (out sb); + + if (sb.ToString () != "This is my message. Isn't it nice?") + return 1; + return 0; + } + + public static int test_0_marshal_stringbuilder_out_unicode () { + StringBuilder sb; + mono_test_marshal_stringbuilder_out_unicode (out sb); + + if (sb.ToString () != "This is my message. Isn't it nice?") + return 1; + return 0; + } + public static int test_0_marshal_empty_string_array () { return mono_test_marshal_empty_string_array (null); } @@ -958,6 +1037,9 @@ public class Tests { [DllImport ("libtest", EntryPoint="mono_test_marshal_amd64_pass_return_struct1")] public static extern Amd64Struct1 mono_test_marshal_amd64_pass_return_struct1 (Amd64Struct1 s); + + [DllImport ("libtest", EntryPoint="mono_test_marshal_amd64_pass_return_struct1_many_args")] + public static extern Amd64Struct1 mono_test_marshal_amd64_pass_return_struct1_many_args (Amd64Struct1 s, int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8); public static int test_0_amd64_struct1 () { Amd64Struct1 s = new Amd64Struct1 (); @@ -971,6 +1053,18 @@ public class Tests { return ((s2.i == 6) && (s2.j == -4) && (s2.k == 0x1000000) && (s2.l == 0x10000000)) ? 0 : 1; } + public static int test_0_amd64_struct1_many_args () { + Amd64Struct1 s = new Amd64Struct1 (); + s.i = 5; + s.j = -5; + s.k = 0xffffff; + s.l = 0xfffffff; + + Amd64Struct1 s2 = mono_test_marshal_amd64_pass_return_struct1_many_args (s, 1, 2, 3, 4, 5, 6, 7, 8); + + return ((s2.i == 6) && (s2.j == -4) && (s2.k == 0x1000000) && (s2.l == 0x10000000 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8)) ? 0 : 1; + } + /* TEST 2: 8 byte long INTEGER struct */ [StructLayout(LayoutKind.Sequential)] @@ -1043,16 +1137,16 @@ public class Tests { } [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 extern TestStruct5 mono_test_marshal_ia64_pass_return_struct5 (double d1, double d2, TestStruct5 s, int i, 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); + TestStruct5 s2 = mono_test_marshal_ia64_pass_return_struct5 (1.0, 2.0, s, 5, 3.0, 4.0); - return (s2.d1 == 8.0 && s2.d2 == 2.0) ? 0 : 1; + return (s2.d1 == 13.0 && s2.d2 == 7.0) ? 0 : 1; } /* Test 6: Double HFA */ @@ -1100,6 +1194,37 @@ public class Tests { return 0; } + /* + * Generic structures + */ + + [StructLayout(LayoutKind.Sequential)] + public struct Amd64Struct1Gen { + public T i; + public T j; + public T k; + public T l; + } + + [DllImport ("libtest", EntryPoint="mono_test_marshal_amd64_pass_return_struct1")] + public static extern Amd64Struct1Gen mono_test_marshal_amd64_pass_return_struct1_gen (Amd64Struct1Gen s); + + public static int test_0_amd64_struct1_gen () { + Amd64Struct1Gen s = new Amd64Struct1Gen (); + s.i = 5; + s.j = -5; + s.k = 0xffffff; + s.l = 0xfffffff; + + Amd64Struct1Gen s2 = mono_test_marshal_amd64_pass_return_struct1_gen (s); + + return ((s2.i == 6) && (s2.j == -4) && (s2.k == 0x1000000) && (s2.l == 0x10000000)) ? 0 : 1; + } + + /* + * Other tests + */ + public static int test_0_marshal_byval_class () { SimpleObj obj0 = new SimpleObj (); obj0.str = "T1"; @@ -1164,10 +1289,23 @@ public class Tests { return mono_test_stdcall_name_mangling (0, 1, 2) == 3 ? 0 : 1; } + /* Float test */ + + [DllImport ("libtest", EntryPoint="mono_test_marshal_pass_return_float")] + public static extern float mono_test_marshal_pass_return_float (float f); + + public static int test_0_pass_return_float () { + float f = mono_test_marshal_pass_return_float (1.5f); + + return (f == 2.5f) ? 0 : 1; + } + /* * Pointers to structures can not be passed */ + /* This seems to be allowed by MS in some cases */ + /* public struct CharInfo { public char Character; public short Attributes; @@ -1189,6 +1327,7 @@ public class Tests { } return 1; } + */ /* * LPWStr marshalling @@ -1316,6 +1455,31 @@ public class Tests { return 0; } + /* + * Alignment of structs containing longs + */ + + struct LongStruct2 { + public long l; + } + + struct LongStruct { + public int i; + public LongStruct2 l; + } + + [DllImport("libtest")] + extern static int mono_test_marshal_long_struct (ref LongStruct s); + + public static int test_47_pass_long_struct () { + LongStruct s = new LongStruct (); + s.i = 5; + s.l = new LongStruct2 (); + s.l.l = 42; + + return mono_test_marshal_long_struct (ref s); + } + /* * Invoking pinvoke methods through delegates */ @@ -1365,5 +1529,172 @@ public class Tests { return 1; } + + /* + * Marshalling of type 'object' + */ + + [DllImport ("libtest", EntryPoint="mono_test_marshal_class")] + public static extern SimpleClass mono_test_marshal_object (int i, int j, int k, object ss, int l); + + public static int test_0_marshal_object () { + try { + mono_test_marshal_object (0, 0, 0, null, 0); + return 1; + } catch (Exception) { + return 0; + } + } + + /* + * Marshalling of DateTime to OLE DATE (double) + */ + [DllImport ("libtest", EntryPoint="mono_test_marshal_date_time")] + public static extern double mono_test_marshal_date_time (DateTime d, out DateTime d2); + + public static int test_0_marshal_date_time () { + DateTime d = new DateTime (2009, 12, 6); + DateTime d2; + double d3 = mono_test_marshal_date_time (d, out d2); + if (d3 != 40153.0) + return 1; + if (d2 != d) + return 2; + return 0; + } + + /* + * Calling pinvoke functions dynamically using calli + */ + + [DllImport("libtest")] + private static extern IntPtr mono_test_marshal_lookup_symbol (string fileName); + + delegate void CalliDel (IntPtr a, int[] f); + + public static int test_0_calli_dynamic () { + /* we need the cdecl version because the icall convention demands it under Windows */ + IntPtr func = mono_test_marshal_lookup_symbol ("mono_test_marshal_inout_array_cdecl"); + + DynamicMethod dm = new DynamicMethod ("calli", typeof (void), new Type [] { typeof (IntPtr), typeof (int[]) }); + + var il = dm.GetILGenerator (); + var signature = SignatureHelper.GetMethodSigHelper (CallingConvention.Cdecl, typeof (void)); + + il.Emit (OpCodes.Ldarg, 1); + signature.AddArgument (typeof (byte[])); + + il.Emit (OpCodes.Ldarg_0); + + il.Emit (OpCodes.Calli, signature); + il.Emit (OpCodes.Ret); + + var f = (CalliDel)dm.CreateDelegate (typeof (CalliDel)); + + int[] arr = new int [1000]; + for (int i = 0; i < 50; ++i) + arr [i] = (int)i; + f (func, arr); + if (arr.Length != 1000) + return 1; + for (int i = 0; i < 50; ++i) + if (arr [i] != 50 - i) + return 2; + + return 0; + } + + + /*char array marshaling */ + [DllImport ("libtest", EntryPoint="mono_test_marshal_ansi_char_array", CharSet=CharSet.Ansi)] + public static extern int mono_test_marshal_ansi_char_array (char[] a1); + + public static int test_0_marshal_ansi_char_array () { + char[] buf = new char [32]; + buf [0] = 'q'; + buf [1] = 'w'; + buf [2] = 'e'; + buf [3] = 'r'; + + if (mono_test_marshal_ansi_char_array (buf) != 0) + return 1; + + string s = new string (buf); + if (s.StartsWith ("qwer")) + return 0; + else + return 2; + } + + /*char array marshaling */ + [DllImport ("libtest", EntryPoint="mono_test_marshal_unicode_char_array", CharSet=CharSet.Unicode)] + public static extern int mono_test_marshal_unicode_char_array (char[] a1); + + public static int test_0_marshal_unicode_char_array () { + char[] buf = new char [32]; + buf [0] = 'q'; + buf [1] = 'w'; + buf [2] = 'e'; + buf [3] = 'r'; + + if (mono_test_marshal_unicode_char_array (buf) != 0) + return 1; + + string s = new string (buf); + if (s.StartsWith ("abcdef")) + return 0; + else + return 2; + } + + [DllImport ("libtest", EntryPoint="mono_test_marshal_lpstr")] + public static extern int mono_test_marshal_lpstr ([MarshalAs(UnmanagedType.LPStr)] string str); + + public static int test_0_mono_test_marshal_lpstr () { + string str = "ABC"; + + if (mono_test_marshal_lpstr (str) != 0) + return 1; + + return 0; + } + + [DllImport ("libtest", EntryPoint="mono_test_marshal_lpwstr")] + public static extern int mono_test_marshal_lpwstr ([MarshalAs(UnmanagedType.LPWStr)] string str); + + public static int test_0_mono_test_marshal_lpwstr () { + string str = "ABC"; + + if (mono_test_marshal_lpwstr (str) != 0) + return 1; + + return 0; + } + + + [method: DllImport ("libtest", EntryPoint="mono_test_marshal_return_lpstr")] + [return: MarshalAs(UnmanagedType.LPStr)] + public static extern string mono_test_marshal_return_lpstr (); + + public static int test_0_mono_test_marshal_return_lpstr () { + string str = mono_test_marshal_return_lpstr (); + if ("XYZ" == str) + return 0; + + return 1; + } + + [method: DllImport ("libtest", EntryPoint="mono_test_marshal_return_lpwstr")] + [return: MarshalAs(UnmanagedType.LPWStr)] + public static extern string mono_test_marshal_return_lpwstr (); + + public static int test_0_mono_test_marshal_return_lpwstr () { + string str = mono_test_marshal_return_lpwstr (); + if ("XYZ" == str) + return 0; + + return 1; + } + }