+//
+// 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 {
public string d2;
}
+ [StructLayout (LayoutKind.Sequential)]
+ public struct SimpleStructGen<T> {
+ 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;
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
[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<string> ss);
[DllImport ("libtest", EntryPoint="mono_test_marshal_struct2")]
public static extern int mono_test_marshal_struct2 (SimpleStruct2 ss);
[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_ref")]
+ public static extern int mono_test_marshal_stringbuilder_ref (ref 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);
return mono_test_marshal_struct (ss);
}
+ public static int test_0_marshal_struct_gen () {
+ SimpleStructGen<string> ss = new SimpleStructGen<string> ();
+ 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;
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);
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);
return 2;
if (res.del2 (2) != 0)
return 3;
+ if (res.del3 != null)
+ return 4;
return 0;
}
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_stringbuilder_ref () {
+ StringBuilder sb = new StringBuilder ();
+ sb.Append ("ABC");
+ int res = mono_test_marshal_stringbuilder_ref (ref sb);
+ if (res != 0)
+ return 1;
+
+ if (sb.ToString () != "This is my message. Isn't it nice?")
+ return 2;
+ return 0;
+ }
+
public static int test_0_marshal_empty_string_array () {
return mono_test_marshal_empty_string_array (null);
}
public static int test_0_marshal_byref_string () {
string res = "TEST1";
- return string_marshal_test2 (ref res);
+ int r = string_marshal_test2 (ref res);
+ if (r != 0)
+ return 1;
+ if (res != "TEST2")
+ return 2;
+ return 0;
}
public static int test_0_marshal_null_string () {
* 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;
}
return 1;
}
+ */
/*
* LPWStr marshalling
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
*/
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;
+ }
+
}