BindingFlags.Public needed here as Exception.HResult is now public in .NET 4.5. This...
[mono.git] / mono / tests / pinvoke2.cs
1 //
2 // Copyright 2011 Xamarin Inc (http://www.xamarin.com).
3 //
4
5 using System;
6 using System.Text;
7 using System.Runtime.InteropServices;
8 using System.Runtime.CompilerServices;
9 using System.Reflection.Emit;
10
11 public class Tests {
12
13         public int int_field;
14
15         public static int delegate_test (int a)
16         {
17                 if (a == 2)
18                         return 0;
19
20                 return 1;
21         }
22
23         public int delegate_test_instance (int a)
24         {
25                 return int_field + a;
26         }
27         
28         [StructLayout (LayoutKind.Sequential)]
29         public struct SimpleStruct {
30                 public bool a;
31                 public bool b;
32                 public bool c;
33                 public string d;
34                 [MarshalAs(UnmanagedType.LPWStr)]
35                 public string d2;
36         }
37
38         [StructLayout (LayoutKind.Sequential)]
39         public struct SimpleStructGen<T> {
40                 public bool a;
41                 public bool b;
42                 public bool c;
43                 public string d;
44                 [MarshalAs(UnmanagedType.LPWStr)]
45                 public string d2;
46         }
47
48         [StructLayout (LayoutKind.Sequential)]
49         public struct SimpleStruct2 {
50                 public bool a;
51                 public bool b;
52                 public bool c;
53                 public string d;
54                 public byte e;
55                 public double f;
56                 public byte g;
57                 public long h;
58         }
59
60         [StructLayout (LayoutKind.Sequential, Size=0)]
61         public struct EmptyStruct {
62         }
63
64         [StructLayout (LayoutKind.Sequential)]
65         public struct DelegateStruct {
66                 public int a;
67                 public SimpleDelegate del;
68                 [MarshalAs(UnmanagedType.FunctionPtr)] 
69                 public SimpleDelegate del2;
70                 [MarshalAs(UnmanagedType.FunctionPtr)] 
71                 public SimpleDelegate del3;
72         }
73
74         /* sparcv9 has complex conventions when passing structs with doubles in them 
75            by value, some simple tests for them */
76         [StructLayout (LayoutKind.Sequential)]
77         public struct Point {
78                 public double x;
79                 public double y;
80         }
81
82         [StructLayout (LayoutKind.Sequential)]
83         public struct MixedPoint {
84                 public int x;
85                 public double y;
86         }
87
88         [StructLayout (LayoutKind.Sequential)]
89         public class SimpleClass {
90                 public bool a;
91                 public bool b;
92                 public bool c;
93                 public string d;
94                 public byte e;
95                 public double f;
96                 public byte g;
97                 public long h;
98         }
99
100         [StructLayout (LayoutKind.Sequential)]
101         public class EmptyClass {
102         }
103
104         [StructLayout (LayoutKind.Sequential)]
105         public struct LongAlignStruct {
106                 public int a;
107                 public long b;
108                 public long c;
109         }
110
111         [StructLayout(LayoutKind.Sequential)]
112         public class BlittableClass
113         {
114                 public int a = 1;
115                 public int b = 2;
116         }
117
118         [StructLayout (LayoutKind.Sequential)]
119         class SimpleObj
120         {
121                 public string str;
122                 public int i;
123         }
124
125         [StructLayout(LayoutKind.Sequential)]
126         struct AsAnyStruct
127         {
128                 public int i;
129                 public int j;
130                 public int k;
131                 public String s;
132
133                 public AsAnyStruct(int i, int j, int k, String s) {
134                         this.i = i;
135                         this.j = j;
136                         this.k = k;
137                         this.s = s;
138                 }
139         }
140
141         [StructLayout(LayoutKind.Sequential)]
142         class AsAnyClass
143         {
144                 public int i;
145                 public int j;
146                 public int k;
147                 public String s;
148
149                 public AsAnyClass(int i, int j, int k, String s) {
150                         this.i = i;
151                         this.j = j;
152                         this.k = k;
153                 }
154         }
155
156         [DllImport ("libnot-found", EntryPoint="not_found")]
157         public static extern int mono_library_not_found ();
158
159         [DllImport ("libtest", EntryPoint="not_found")]
160         public static extern int mono_entry_point_not_found ();
161
162         [DllImport ("libtest.dll", EntryPoint="mono_test_marshal_char")]
163         public static extern int mono_test_marshal_char_2 (char a1);
164
165         [DllImport ("test", EntryPoint="mono_test_marshal_char")]
166         public static extern int mono_test_marshal_char_3 (char a1);
167
168         [DllImport ("libtest", EntryPoint="mono_test_marshal_char")]
169         public static extern int mono_test_marshal_char (char a1);
170
171         [DllImport ("libtest", EntryPoint="mono_test_marshal_char_array", CharSet=CharSet.Unicode)]
172         public static extern int mono_test_marshal_char_array (char[] a1);
173
174         [DllImport ("libtest", EntryPoint="mono_test_marshal_bool_byref")]
175         public static extern int mono_test_marshal_bool_byref (int a, ref bool b, int c);
176
177         [DllImport ("libtest", EntryPoint="mono_test_marshal_bool_in_as_I1_U1")]
178         public static extern int mono_test_marshal_bool_in_as_I1 ([MarshalAs (UnmanagedType.I1)] bool bTrue, [MarshalAs (UnmanagedType.I1)] bool bFalse);
179
180         [DllImport ("libtest", EntryPoint="mono_test_marshal_bool_in_as_I1_U1")]
181         public static extern int mono_test_marshal_bool_in_as_U1 ([MarshalAs (UnmanagedType.U1)] bool bTrue, [MarshalAs (UnmanagedType.U1)] bool bFalse);
182
183         [DllImport ("libtest", EntryPoint="mono_test_marshal_bool_out_as_I1_U1")]
184         public static extern int mono_test_marshal_bool_out_as_I1 ([MarshalAs (UnmanagedType.I1)] out bool bTrue, [MarshalAs (UnmanagedType.I1)] out bool bFalse);
185
186         [DllImport ("libtest", EntryPoint="mono_test_marshal_bool_out_as_I1_U1")]
187         public static extern int mono_test_marshal_bool_out_as_U1 ([MarshalAs (UnmanagedType.U1)] out bool bTrue, [MarshalAs (UnmanagedType.U1)] out bool bFalse);
188
189         [DllImport ("libtest", EntryPoint="mono_test_marshal_bool_ref_as_I1_U1")]
190         public static extern int mono_test_marshal_bool_ref_as_I1 ([MarshalAs (UnmanagedType.I1)] ref bool bTrue, [MarshalAs (UnmanagedType.I1)] ref bool bFalse);
191
192         [DllImport ("libtest", EntryPoint="mono_test_marshal_bool_ref_as_I1_U1")]
193         public static extern int mono_test_marshal_bool_ref_as_U1 ([MarshalAs (UnmanagedType.U1)] ref bool bTrue, [MarshalAs (UnmanagedType.U1)] ref bool bFalse);
194
195         [DllImport ("libtest", EntryPoint="mono_test_marshal_array")]
196         public static extern int mono_test_marshal_array (int [] a1);
197
198         [DllImport ("libtest", EntryPoint="mono_test_marshal_empty_string_array")]
199         public static extern int mono_test_marshal_empty_string_array (string [] a1);
200
201         [DllImport ("libtest", EntryPoint="mono_test_marshal_string_array")]
202         public static extern int mono_test_marshal_string_array (string [] a1);
203
204         [DllImport ("libtest", EntryPoint="mono_test_marshal_unicode_string_array", CharSet=CharSet.Unicode)]
205         public static extern int mono_test_marshal_unicode_string_array (string [] a1, [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.LPStr)]string [] a2);
206
207         [DllImport ("libtest", EntryPoint="mono_test_marshal_stringbuilder_array")]
208         public static extern int mono_test_marshal_stringbuilder_array (StringBuilder [] a1);   
209
210         [DllImport ("libtest", EntryPoint="mono_test_marshal_inout_array")]
211         public static extern int mono_test_marshal_inout_array ([In, Out] int [] a1);
212
213         [DllImport ("libtest", EntryPoint="mono_test_marshal_out_array")]
214         public static extern int mono_test_marshal_out_array ([Out] [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] int [] a1, int n);
215
216         [DllImport ("libtest", EntryPoint="mono_test_marshal_inout_nonblittable_array", CharSet = CharSet.Unicode)]
217         public static extern int mono_test_marshal_inout_nonblittable_array ([In, Out] char [] a1);
218         
219         [DllImport ("libtest", EntryPoint="mono_test_marshal_struct")]
220         public static extern int mono_test_marshal_struct (SimpleStruct ss);
221         
222         [DllImport ("libtest", EntryPoint="mono_test_marshal_struct")]
223         public static extern int mono_test_marshal_struct_gen (SimpleStructGen<string> ss);
224
225         [DllImport ("libtest", EntryPoint="mono_test_marshal_struct2")]
226         public static extern int mono_test_marshal_struct2 (SimpleStruct2 ss);
227
228         [DllImport ("libtest", EntryPoint="mono_test_marshal_struct2_2")]
229         public static extern int mono_test_marshal_struct2_2 (int i, int j, int k, SimpleStruct2 ss);
230
231         [DllImport ("libtest", EntryPoint="mono_test_marshal_byref_struct")]
232         public static extern int mono_test_marshal_byref_struct (ref SimpleStruct ss, bool a, bool b, bool c, String d);
233
234         [DllImport ("libtest", EntryPoint="mono_test_marshal_byref_struct")]
235         public static extern int mono_test_marshal_byref_struct_in ([In] ref SimpleStruct ss, bool a, bool b, bool c, String d);
236
237         [DllImport ("libtest", EntryPoint="mono_test_marshal_byref_struct")]
238         public static extern int mono_test_marshal_byref_struct_inout ([In, Out] ref SimpleStruct ss, bool a, bool b, bool c, String d);
239
240         [DllImport ("libtest", EntryPoint="mono_test_marshal_point")]
241         public static extern int mono_test_marshal_point (Point p);
242
243         [DllImport ("libtest", EntryPoint="mono_test_marshal_mixed_point")]
244         public static extern int mono_test_marshal_mixed_point (MixedPoint p);
245
246         [DllImport ("libtest", EntryPoint="mono_test_empty_struct")]
247         public static extern int mono_test_empty_struct (int a, EmptyStruct es, int b);
248
249         [DllImport ("libtest", EntryPoint="mono_test_marshal_lpstruct")]
250         public static extern int mono_test_marshal_lpstruct ([In, MarshalAs(UnmanagedType.LPStruct)] SimpleStruct ss);
251
252         [DllImport ("libtest", EntryPoint="mono_test_marshal_lpstruct_blittable")]
253         public static extern int mono_test_marshal_lpstruct_blittable ([In, MarshalAs(UnmanagedType.LPStruct)] Point p);
254
255         [DllImport ("libtest", EntryPoint="mono_test_marshal_struct_array")]
256         public static extern int mono_test_marshal_struct_array (SimpleStruct2[] ss);
257
258         [DllImport ("libtest", EntryPoint="mono_test_marshal_long_align_struct_array")]
259         public static extern int mono_test_marshal_long_align_struct_array (LongAlignStruct[] ss);
260
261         [DllImport ("libtest", EntryPoint="mono_test_marshal_class")]
262         public static extern SimpleClass mono_test_marshal_class (int i, int j, int k, SimpleClass ss, int l);
263
264         [DllImport ("libtest", EntryPoint="mono_test_marshal_byref_class")]
265         public static extern int mono_test_marshal_byref_class (ref SimpleClass ss);
266
267         [DllImport ("libtest", EntryPoint="mono_test_marshal_delegate")]
268         public static extern int mono_test_marshal_delegate (SimpleDelegate d);
269
270         [DllImport ("libtest", EntryPoint="mono_test_marshal_delegate_struct")]
271         public static extern DelegateStruct mono_test_marshal_delegate_struct (DelegateStruct d);
272
273         [DllImport ("libtest", EntryPoint="mono_test_marshal_return_delegate")]
274         public static extern SimpleDelegate mono_test_marshal_return_delegate (SimpleDelegate d);
275
276         [DllImport ("libtest", EntryPoint="mono_test_return_vtype")]
277         public static extern SimpleStruct mono_test_return_vtype (IntPtr i);
278
279         [DllImport ("libtest", EntryPoint="mono_test_marshal_stringbuilder")]
280         public static extern void mono_test_marshal_stringbuilder (StringBuilder sb, int len);
281
282         [DllImport ("libtest", EntryPoint="mono_test_marshal_stringbuilder_default")]
283         public static extern void mono_test_marshal_stringbuilder_default (StringBuilder sb, int len);
284
285         [DllImport ("libtest", EntryPoint="mono_test_marshal_stringbuilder_unicode", CharSet=CharSet.Unicode)]
286         public static extern void mono_test_marshal_stringbuilder_unicode (StringBuilder sb, int len);
287
288         [DllImport ("libtest", EntryPoint="mono_test_marshal_stringbuilder_out")]
289         public static extern void mono_test_marshal_stringbuilder_out (out StringBuilder sb);
290
291         [DllImport ("libtest", EntryPoint="mono_test_marshal_stringbuilder_out_unicode", CharSet=CharSet.Unicode)]
292         public static extern void mono_test_marshal_stringbuilder_out_unicode (out StringBuilder sb);
293
294         [DllImport ("libtest", EntryPoint="mono_test_last_error", SetLastError=true)]
295         public static extern void mono_test_last_error (int err);
296
297         [DllImport ("libtest", EntryPoint="mono_test_asany")]
298         public static extern int mono_test_asany ([MarshalAs (UnmanagedType.AsAny)] object o, int what);
299
300         [DllImport ("libtest", EntryPoint="mono_test_asany", CharSet=CharSet.Unicode)]
301         public static extern int mono_test_asany_unicode ([MarshalAs (UnmanagedType.AsAny)] object o, int what);
302
303         [DllImport("libtest", EntryPoint="mono_test_marshal_asany_in")]
304         static extern void mono_test_asany_in ([MarshalAs(UnmanagedType.AsAny)][In] object obj); 
305
306         [DllImport("libtest", EntryPoint="mono_test_marshal_asany_out")]
307         static extern void mono_test_asany_out ([MarshalAs(UnmanagedType.AsAny)][Out] object obj); 
308         [DllImport("libtest", EntryPoint="mono_test_marshal_asany_inout")]
309         static extern void mono_test_asany_inout ([MarshalAs(UnmanagedType.AsAny)][In, Out] object obj); 
310
311         [DllImport ("libtest")]
312         static extern int class_marshal_test0 (SimpleObj obj);
313
314         [DllImport ("libtest")]
315         static extern void class_marshal_test1 (out SimpleObj obj);
316
317         [DllImport ("libtest")]
318         static extern int class_marshal_test4 (SimpleObj obj);
319         
320         [DllImport ("libtest")]
321         static extern int string_marshal_test0 (string str);
322
323         [DllImport ("libtest")]
324         static extern void string_marshal_test1 (out string str);
325
326         [DllImport ("libtest")]
327         static extern int string_marshal_test2 (ref string str);
328
329         [DllImport ("libtest")]
330         static extern int string_marshal_test3 (string str);
331
332         public delegate int SimpleDelegate (int a);
333
334         public static int Main (string[] args) {
335                 return TestDriver.RunTests (typeof (Tests), args);
336         }
337
338         public static int test_0_marshal_char () {
339                 return mono_test_marshal_char ('a');
340         }
341
342         public static int test_0_marshal_char_array () {
343                 // a unicode char[] is implicitly marshalled as [Out]
344                 char[] buf = new char [32];
345                 mono_test_marshal_char_array (buf);
346                 string s = new string (buf);
347                 if (s.StartsWith ("abcdef"))
348                         return 0;
349                 else
350                         return 1;
351         }
352
353         public static int test_1225_marshal_array () {
354                 int [] a1 = new int [50];
355                 for (int i = 0; i < 50; i++)
356                         a1 [i] = i;
357
358                 return mono_test_marshal_array (a1);
359         }
360
361         public static int test_1225_marshal_inout_array () {
362                 int [] a1 = new int [50];
363                 for (int i = 0; i < 50; i++)
364                         a1 [i] = i;
365
366                 int res = mono_test_marshal_inout_array (a1);
367
368                 for (int i = 0; i < 50; i++)
369                         if (a1 [i] != 50 - i) {
370                                 Console.WriteLine ("X: " + i + " " + a1 [i]);
371                                 return 2;
372                         }
373
374                 return res;
375         }
376
377         public static int test_0_marshal_out_array () {
378                 int [] a1 = new int [50];
379
380                 int res = mono_test_marshal_out_array (a1, 0);
381
382                 for (int i = 0; i < 50; i++)
383                         if (a1 [i] != i) {
384                                 Console.WriteLine ("X: " + i + " " + a1 [i]);
385                                 return 2;
386                         }
387
388                 return 0;
389         }
390
391         public static int test_0_marshal_inout_nonblittable_array () {
392                 char [] a1 = new char [10];
393                 for (int i = 0; i < 10; i++)
394                         a1 [i] = "Hello, World" [i];
395
396                 int res = mono_test_marshal_inout_nonblittable_array (a1);
397
398                 for (int i = 0; i < 10; i++)
399                         if (a1 [i] != 'F')
400                                 return 2;
401
402                 return res;
403         }
404
405         public static int test_0_marshal_struct () {
406                 SimpleStruct ss = new  SimpleStruct ();
407                 ss.b = true;
408                 ss.d = "TEST";
409                 
410                 return mono_test_marshal_struct (ss);
411         }
412
413         public static int test_0_marshal_struct_gen () {
414                 SimpleStructGen<string> ss = new  SimpleStructGen<string> ();
415                 ss.b = true;
416                 ss.d = "TEST";
417                 
418                 return mono_test_marshal_struct_gen (ss);
419         }
420
421         public static int test_0_marshal_struct2 () {
422                 SimpleStruct2 ss2 = new  SimpleStruct2 ();
423                 ss2.b = true;
424                 ss2.d = "TEST";
425                 ss2.e = 99;
426                 ss2.f = 1.5;
427                 ss2.g = 42;
428                 ss2.h = 123L;
429
430                 return mono_test_marshal_struct2 (ss2);
431         }
432
433         public static int test_0_marshal_struct3 () {
434                 SimpleStruct2 ss2 = new  SimpleStruct2 ();
435                 ss2.b = true;
436                 ss2.d = "TEST";
437                 ss2.e = 99;
438                 ss2.f = 1.5;
439                 ss2.g = 42;
440                 ss2.h = 123L;
441
442                 return mono_test_marshal_struct2_2 (10, 11, 12, ss2);
443         }
444
445         public static int test_0_marshal_empty_struct () {
446                 EmptyStruct es = new EmptyStruct ();
447
448                 if (mono_test_empty_struct (1, es, 2) != 0)
449                         return 1;
450                 
451                 return 0;
452         }
453
454         public static int test_0_marshal_lpstruct () {
455                 SimpleStruct ss = new  SimpleStruct ();
456                 ss.b = true;
457                 ss.d = "TEST";
458                 
459                 return mono_test_marshal_lpstruct (ss);
460         }
461
462         public static int test_0_marshal_lpstruct_blittable () {
463                 Point p = new Point ();
464                 p.x = 1.0;
465                 p.y = 2.0;
466                 
467                 return mono_test_marshal_lpstruct_blittable (p);
468         }
469
470         public static int test_0_marshal_struct_array () {
471                 SimpleStruct2[] ss_arr = new SimpleStruct2 [2];
472
473                 SimpleStruct2 ss2 = new SimpleStruct2 ();
474                 ss2.b = true;
475                 ss2.d = "TEST";
476                 ss2.e = 99;
477                 ss2.f = 1.5;
478                 ss2.g = 42;
479                 ss2.h = 123L;
480
481                 ss_arr [0] = ss2;
482
483                 ss2.b = false;
484                 ss2.d = "TEST2";
485                 ss2.e = 100;
486                 ss2.f = 2.5;
487                 ss2.g = 43;
488                 ss2.h = 124L;
489
490                 ss_arr [1] = ss2;
491
492                 return mono_test_marshal_struct_array (ss_arr);
493         }
494
495         public static int test_105_marshal_long_align_struct_array () {
496                 LongAlignStruct[] ss_arr = new LongAlignStruct [2];
497
498                 LongAlignStruct ss = new LongAlignStruct ();
499                 ss.a = 5;
500                 ss.b = 10;
501                 ss.c = 15;
502
503                 ss_arr [0] = ss;
504
505                 ss.a = 20;
506                 ss.b = 25;
507                 ss.c = 30;
508
509                 ss_arr [1] = ss;
510
511                 return mono_test_marshal_long_align_struct_array (ss_arr);
512         }
513
514         /* Test classes as arguments and return values */
515         public static int test_0_marshal_class () {
516                 SimpleClass ss = new  SimpleClass ();
517                 ss.b = true;
518                 ss.d = "TEST";
519                 ss.e = 99;
520                 ss.f = 1.5;
521                 ss.g = 42;
522                 ss.h = 123L;
523
524                 SimpleClass res = mono_test_marshal_class (10, 11, 12, ss, 14);
525                 if (res == null)
526                         return 1;
527                 if  (! (res.a == ss.a && res.b == ss.b && res.c == ss.c && 
528                                 res.d == ss.d && res.e == ss.e && res.f == ss.f &&
529                                 res.g == ss.g && res.h == ss.h))
530                         return 2;
531
532                 /* Test null arguments and results */
533                 res = mono_test_marshal_class (10, 11, 12, null, 14);
534                 if (res != null)
535                         return 3;
536
537                 return 0;
538         }
539
540         public static int test_0_marshal_byref_class () {
541                 SimpleClass ss = new  SimpleClass ();
542                 ss.b = true;
543                 ss.d = "TEST";
544                 ss.e = 99;
545                 ss.f = 1.5;
546                 ss.g = 42;
547                 ss.h = 123L;
548
549                 int res = mono_test_marshal_byref_class (ref ss);
550                 if (ss.d != "TEST-RES")
551                         return 1;
552
553                 return 0;
554         }
555
556         public static int test_0_marshal_delegate () {
557                 SimpleDelegate d = new SimpleDelegate (delegate_test);
558
559                 return mono_test_marshal_delegate (d);
560         }
561
562         public static int test_34_marshal_instance_delegate () {
563                 Tests t = new Tests ();
564                 t.int_field = 32;
565                 SimpleDelegate d = new SimpleDelegate (t.delegate_test_instance);
566
567                 return mono_test_marshal_delegate (d);
568         }
569
570         /* Static delegates closed over their first argument */
571         public static int closed_delegate (Tests t, int a) {
572                 return t.int_field + a;
573         }
574
575         public static int test_34_marshal_closed_static_delegate () {
576                 Tests t = new Tests ();
577                 t.int_field = 32;
578                 SimpleDelegate d = (SimpleDelegate)Delegate.CreateDelegate (typeof (SimpleDelegate), t, typeof (Tests).GetMethod ("closed_delegate"));
579
580                 return mono_test_marshal_delegate (d);
581         }
582
583         public static int test_0_marshal_return_delegate () {
584                 SimpleDelegate d = new SimpleDelegate (delegate_test);
585
586                 SimpleDelegate d2 = mono_test_marshal_return_delegate (d);
587
588                 return d2 (2);
589         }
590
591         public static int test_0_marshal_delegate_struct () {
592                 DelegateStruct s = new DelegateStruct ();
593
594                 s.a = 2;
595                 s.del = new SimpleDelegate (delegate_test);
596                 s.del2 = new SimpleDelegate (delegate_test);
597                 s.del3 = null;
598
599                 DelegateStruct res = mono_test_marshal_delegate_struct (s);
600
601                 if (res.a != 0)
602                         return 1;
603                 if (res.del (2) != 0)
604                         return 2;
605                 if (res.del2 (2) != 0)
606                         return 3;
607                 if (res.del3 != null)
608                         return 4;
609
610                 return 0;
611         }
612
613         [DllImport ("libtest", EntryPoint="mono_test_marshal_out_delegate")]
614         public static extern int mono_test_marshal_out_delegate (out SimpleDelegate d);
615
616         public static int test_3_marshal_out_delegate () {
617                 SimpleDelegate d = null;
618
619                 mono_test_marshal_out_delegate (out d);
620
621                 return d (2);
622         }
623
624         public static int test_0_marshal_byref_struct () {
625                 SimpleStruct s = new SimpleStruct ();
626                 s.a = true;
627                 s.b = false;
628                 s.c = true;
629                 s.d = "ABC";
630                 s.d2 = "DEF";
631
632                 int res = mono_test_marshal_byref_struct (ref s, true, false, true, "ABC");
633                 if (res != 0)
634                         return 1;
635                 if (s.a != false || s.b != true || s.c != false || s.d != "DEF")
636                         return 2;
637                 return 0;
638         }
639
640         public static int test_0_marshal_byref_struct_in () {
641                 SimpleStruct s = new SimpleStruct ();
642                 s.a = true;
643                 s.b = false;
644                 s.c = true;
645                 s.d = "ABC";
646                 s.d2 = "DEF";
647
648                 int res = mono_test_marshal_byref_struct_in (ref s, true, false, true, "ABC");
649                 if (res != 0)
650                         return 1;
651                 if (s.a != true || s.b != false || s.c != true || s.d != "ABC")
652                         return 2;
653                 return 0;
654         }
655
656         public static int test_0_marshal_byref_struct_inout () {
657                 SimpleStruct s = new SimpleStruct ();
658                 s.a = true;
659                 s.b = false;
660                 s.c = true;
661                 s.d = "ABC";
662                 s.d2 = "DEF";
663
664                 int res = mono_test_marshal_byref_struct_inout (ref s, true, false, true, "ABC");
665                 if (res != 0)
666                         return 1;
667                 if (s.a != false || s.b != true || s.c != false || s.d != "DEF")
668                         return 2;
669                 return 0;
670         }
671
672         public static int test_0_marshal_point () {
673                 Point pt = new Point();
674                 pt.x = 1.25;
675                 pt.y = 3.5;
676                 
677                 return mono_test_marshal_point(pt);
678         }
679
680         public static int test_0_marshal_mixed_point () {
681                 MixedPoint mpt = new MixedPoint();
682                 mpt.x = 5;
683                 mpt.y = 6.75;
684                 
685                 return mono_test_marshal_mixed_point(mpt);
686         }
687
688         public static int test_0_marshal_bool_byref () {
689                 bool b = true;
690                 if (mono_test_marshal_bool_byref (99, ref b, 100) != 1)
691                         return 1;
692                 b = false;
693                 if (mono_test_marshal_bool_byref (99, ref b, 100) != 0)
694                         return 12;
695                 if (b != true)
696                         return 13;
697
698                 return 0;
699         }
700
701         public static int test_0_marshal_bool_as_I1 () {
702
703                 int ret;
704                 bool bTrue, bFalse;
705                 if ((ret = mono_test_marshal_bool_in_as_I1 (true, false)) != 0)
706                         return ret;
707
708                 if ((ret = mono_test_marshal_bool_out_as_I1 (out bTrue, out bFalse)) != 0)
709                         return ret;
710
711                 if(!bTrue)
712                         return 10;
713
714                 if(bFalse)
715                         return 11;
716
717                 if ((ret = mono_test_marshal_bool_ref_as_I1 (ref bTrue, ref bFalse)) != 0)
718                         return ret;
719
720                 if(bTrue)
721                         return 12;
722
723                 if(!bFalse)
724                         return 13;
725
726                 return 0;
727         }
728
729         public static int test_0_marshal_bool_as_U1 () {
730
731                 int ret;
732                 bool bTrue, bFalse;
733                 if ((ret = mono_test_marshal_bool_in_as_U1 (true, false)) != 0)
734                         return ret;
735
736                 if ((ret = mono_test_marshal_bool_out_as_U1 (out bTrue, out bFalse)) != 0)
737                         return ret;
738
739                 if(!bTrue)
740                         return 10;
741
742                 if(bFalse)
743                         return 11;
744
745                 if ((ret = mono_test_marshal_bool_ref_as_U1 (ref bTrue, ref bFalse)) != 0)
746                         return ret;
747
748                 if(bTrue)
749                         return 12;
750
751                 if(!bFalse)
752                         return 13;
753
754                 return 0;
755         }
756
757         public static int test_0_return_vtype () {
758                 SimpleStruct ss = mono_test_return_vtype (new IntPtr (5));
759
760                 if (!ss.a && ss.b && !ss.c && ss.d == "TEST" && ss.d2 == "TEST2")
761                         return 0;
762
763                 return 1;
764         }
765
766         public static int test_0_marshal_stringbuilder () {
767                 StringBuilder sb = new StringBuilder(255);
768                 sb.Append ("ABCD");
769                 mono_test_marshal_stringbuilder (sb, sb.Capacity);
770                 String res = sb.ToString();
771
772                 if (res != "This is my message.  Isn't it nice?")
773                         return 1;  
774
775                 // Test StringBuilder with default capacity (16)
776                 StringBuilder sb2 = new StringBuilder();
777                 mono_test_marshal_stringbuilder_default (sb2, sb2.Capacity);
778                 if (sb2.ToString () != "This is my messa")
779                         return 2;
780
781                 return 0;
782         }
783
784         public static int test_0_marshal_stringbuilder_unicode () {
785                 StringBuilder sb = new StringBuilder(255);
786                 mono_test_marshal_stringbuilder_unicode (sb, sb.Capacity);
787                 String res = sb.ToString();
788
789                 if (res != "This is my message.  Isn't it nice?")
790                         return 1;  
791
792                 // Test StringBuilder with default capacity (16)
793                 StringBuilder sb2 = new StringBuilder();
794                 mono_test_marshal_stringbuilder_unicode (sb2, sb2.Capacity);
795                 if (sb2.ToString () != "This is my messa")
796                         return 2;
797                 
798                 return 0;
799         }
800
801         public static int test_0_marshal_stringbuilder_out () {
802                 StringBuilder sb;
803                 mono_test_marshal_stringbuilder_out (out sb);
804                 
805                 if (sb.ToString () != "This is my message.  Isn't it nice?")
806                         return 1;  
807                 return 0;
808         }
809
810         public static int test_0_marshal_stringbuilder_out_unicode () {
811                 StringBuilder sb;
812                 mono_test_marshal_stringbuilder_out_unicode (out sb);
813
814                 if (sb.ToString () != "This is my message.  Isn't it nice?")
815                         return 1;  
816                 return 0;
817         }
818
819         public static int test_0_marshal_empty_string_array () {
820                 return mono_test_marshal_empty_string_array (null);
821         }
822
823         public static int test_0_marshal_string_array () {
824                 return mono_test_marshal_string_array (new String [] { "ABC", "DEF" });
825         }
826
827         public static int test_0_marshal_unicode_string_array () {
828                 return mono_test_marshal_unicode_string_array (new String [] { "ABC", "DEF" }, new String [] { "ABC", "DEF" });
829         }
830
831         public static int test_0_marshal_stringbuilder_array () {
832                 StringBuilder sb1 = new StringBuilder ("ABC");
833                 StringBuilder sb2 = new StringBuilder ("DEF");
834
835                 int res = mono_test_marshal_stringbuilder_array (new StringBuilder [] { sb1, sb2 });
836                 if (res != 0)
837                         return res;
838                 if (sb1.ToString () != "DEF")
839                         return 5;
840                 if (sb2.ToString () != "ABC")
841                         return 6;
842                 return 0;
843         }
844
845         public static int test_0_last_error () {
846                 mono_test_last_error (5);
847                 if (Marshal.GetLastWin32Error () == 5)
848                         return 0;
849                 else
850                         return 1;
851         }
852
853         public static int test_0_entry_point_not_found () {
854
855                 try {
856                         mono_entry_point_not_found ();
857                         return 1;
858                 }
859                 catch (EntryPointNotFoundException) {
860                 }
861
862                 return 0;
863         }
864
865         public static int test_0_library_not_found () {
866
867                 try {
868                         mono_library_not_found ();
869                         return 1;
870                 }
871                 catch (DllNotFoundException) {
872                 }
873
874                 return 0;
875         }
876
877         /* Check that the runtime trims .dll from the library name */
878         public static int test_0_trim_dll_from_name () {
879
880                 mono_test_marshal_char_2 ('A');
881
882                 return 0;
883         }
884
885         /* Check that the runtime adds lib to to the library name */
886         public static int test_0_add_lib_to_name () {
887
888                 mono_test_marshal_char_3 ('A');
889
890                 return 0;
891         }
892
893         class C {
894                 public int i;
895         }
896
897         public static int test_0_asany () {
898                 if (mono_test_asany (5, 1) != 0)
899                         return 1;
900
901                 if (mono_test_asany ("ABC", 2) != 0)
902                         return 2;
903
904                 SimpleStruct2 ss2 = new  SimpleStruct2 ();
905                 ss2.b = true;
906                 ss2.d = "TEST";
907                 ss2.e = 99;
908                 ss2.f = 1.5;
909                 ss2.g = 42;
910                 ss2.h = 123L;
911
912                 if (mono_test_asany (ss2, 3) != 0)
913                         return 3;
914
915                 if (mono_test_asany_unicode ("ABC", 4) != 0)
916                         return 4;
917
918                 try {
919                         C c = new C ();
920                         c.i = 5;
921                         mono_test_asany (c, 0);
922                         return 5;
923                 }
924                 catch (ArgumentException) {
925                 }
926
927                 try {
928                         mono_test_asany (new Object (), 0);
929                         return 6;
930                 }
931                 catch (ArgumentException) {
932                 }
933
934                 return 0;
935         }
936
937         /* AsAny marshalling + [In, Out] */
938
939         public static int test_0_asany_in () {
940                 // Struct
941                 AsAnyStruct str = new AsAnyStruct(1,2,3, "ABC");
942                 mono_test_asany_in (str);
943
944                 // Formatted Class
945                 AsAnyClass cls = new AsAnyClass(1,2,3, "ABC");
946                 mono_test_asany_in (cls);
947                 if ((cls.i != 1) || (cls.j != 2) || (cls.k != 3))
948                         return 1;
949
950                 // Boxed Struct
951                 object obj = new AsAnyStruct(1,2,3, "ABC");
952                 mono_test_asany_in (obj);
953                 str = (AsAnyStruct)obj;
954                 if ((str.i != 1) || (str.j != 2) || (str.k != 3))
955                         return 2;
956
957                 return 0;
958         }
959
960         public static int test_0_asany_out () {
961                 // Struct
962                 AsAnyStruct str = new AsAnyStruct(1,2,3, "ABC");
963                 mono_test_asany_out (str);
964
965                 // Formatted Class
966                 AsAnyClass cls = new AsAnyClass(1,2,3, "ABC");
967                 mono_test_asany_out (cls);
968                 if ((cls.i != 10) || (cls.j != 20) || (cls.k != 30))
969                         return 1;
970
971                 // Boxed Struct
972                 object obj = new AsAnyStruct(1,2,3, "ABC");
973                 mono_test_asany_out (obj);
974                 str = (AsAnyStruct)obj;
975                 if ((str.i != 10) || (str.j != 20) || (str.k != 30))
976                         return 2;
977
978                 return 0;
979         }
980
981         public static int test_0_asany_inout () {
982                 // Struct
983                 AsAnyStruct str = new AsAnyStruct(1,2,3, "ABC");
984                 mono_test_asany_inout (str);
985
986                 // Formatted Class
987                 AsAnyClass cls = new AsAnyClass(1,2,3, "ABC");
988                 mono_test_asany_inout (cls);
989                 if ((cls.i != 10) || (cls.j != 20) || (cls.k != 30))
990                         return 1;
991
992                 // Boxed Struct
993                 object obj = new AsAnyStruct(1,2,3, "ABC");
994                 mono_test_asany_inout (obj);
995                 str = (AsAnyStruct)obj;
996                 if ((str.i != 10) || (str.j != 20) || (str.k != 30))
997                         return 2;
998
999                 return 0;
1000         }
1001
1002         /* Byref String Array */
1003
1004         [DllImport ("libtest", EntryPoint="mono_test_marshal_byref_string_array")]
1005         public static extern int mono_test_marshal_byref_string_array (ref string[] data);
1006
1007         public static int test_0_byref_string_array () {
1008
1009                 string[] arr = null;
1010
1011                 if (mono_test_marshal_byref_string_array (ref arr) != 0)
1012                         return 1;
1013
1014                 arr = new string[] { "Alpha", "Beta", "Gamma" };
1015
1016                 if (mono_test_marshal_byref_string_array (ref arr) != 1)
1017                         return 2;
1018
1019                 /* FIXME: Test returned array and out case */
1020
1021                 return 0;
1022         }
1023
1024         /*
1025          * AMD64 small structs-by-value tests.
1026          */
1027
1028         /* TEST 1: 16 byte long INTEGER struct */
1029
1030         [StructLayout(LayoutKind.Sequential)]
1031         public struct Amd64Struct1 {
1032                 public int i;
1033                 public int j;
1034                 public int k;
1035                 public int l;
1036         }
1037         
1038         [DllImport ("libtest", EntryPoint="mono_test_marshal_amd64_pass_return_struct1")]
1039         public static extern Amd64Struct1 mono_test_marshal_amd64_pass_return_struct1 (Amd64Struct1 s);
1040         
1041         [DllImport ("libtest", EntryPoint="mono_test_marshal_amd64_pass_return_struct1_many_args")]
1042         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);
1043
1044         public static int test_0_amd64_struct1 () {
1045                 Amd64Struct1 s = new Amd64Struct1 ();
1046                 s.i = 5;
1047                 s.j = -5;
1048                 s.k = 0xffffff;
1049                 s.l = 0xfffffff;
1050
1051                 Amd64Struct1 s2 = mono_test_marshal_amd64_pass_return_struct1 (s);
1052
1053                 return ((s2.i == 6) && (s2.j == -4) && (s2.k == 0x1000000) && (s2.l == 0x10000000)) ? 0 : 1;
1054         }
1055
1056         public static int test_0_amd64_struct1_many_args () {
1057                 Amd64Struct1 s = new Amd64Struct1 ();
1058                 s.i = 5;
1059                 s.j = -5;
1060                 s.k = 0xffffff;
1061                 s.l = 0xfffffff;
1062
1063                 Amd64Struct1 s2 = mono_test_marshal_amd64_pass_return_struct1_many_args (s, 1, 2, 3, 4, 5, 6, 7, 8);
1064
1065                 return ((s2.i == 6) && (s2.j == -4) && (s2.k == 0x1000000) && (s2.l == 0x10000000 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8)) ? 0 : 1;
1066         }
1067
1068         /* TEST 2: 8 byte long INTEGER struct */
1069
1070         [StructLayout(LayoutKind.Sequential)]
1071         public struct Amd64Struct2 {
1072                 public int i;
1073                 public int j;
1074         }
1075         
1076         [DllImport ("libtest", EntryPoint="mono_test_marshal_amd64_pass_return_struct2")]
1077         public static extern Amd64Struct2 mono_test_marshal_amd64_pass_return_struct2 (Amd64Struct2 s);
1078
1079         public static int test_0_amd64_struct2 () {
1080                 Amd64Struct2 s = new Amd64Struct2 ();
1081                 s.i = 5;
1082                 s.j = -5;
1083
1084                 Amd64Struct2 s2 = mono_test_marshal_amd64_pass_return_struct2 (s);
1085
1086                 return ((s2.i == 6) && (s2.j == -4)) ? 0 : 1;
1087         }
1088
1089         /* TEST 3: 4 byte long INTEGER struct */
1090
1091         [StructLayout(LayoutKind.Sequential)]
1092         public struct Amd64Struct3 {
1093                 public int i;
1094         }
1095         
1096         [DllImport ("libtest", EntryPoint="mono_test_marshal_amd64_pass_return_struct3")]
1097         public static extern Amd64Struct3 mono_test_marshal_amd64_pass_return_struct3 (Amd64Struct3 s);
1098
1099         public static int test_0_amd64_struct3 () {
1100                 Amd64Struct3 s = new Amd64Struct3 ();
1101                 s.i = -5;
1102
1103                 Amd64Struct3 s2 = mono_test_marshal_amd64_pass_return_struct3 (s);
1104
1105                 return (s2.i == -4) ? 0 : 1;
1106         }
1107
1108         /* Test 4: 16 byte long FLOAT struct */
1109
1110         [StructLayout(LayoutKind.Sequential)]
1111         public struct Amd64Struct4 {
1112                 public double d1, d2;
1113         }
1114         
1115         [DllImport ("libtest", EntryPoint="mono_test_marshal_amd64_pass_return_struct4")]
1116         public static extern Amd64Struct4 mono_test_marshal_amd64_pass_return_struct4 (Amd64Struct4 s);
1117
1118         public static int test_0_amd64_struct4 () {
1119                 Amd64Struct4 s = new Amd64Struct4 ();
1120                 s.d1 = 5.0;
1121                 s.d2 = -5.0;
1122
1123                 Amd64Struct4 s2 = mono_test_marshal_amd64_pass_return_struct4 (s);
1124
1125                 return (s2.d1 == 6.0 && s2.d2 == -4.0) ? 0 : 1;
1126         }
1127
1128         /*
1129          * IA64 struct tests
1130          */
1131
1132         /* Test 5: Float HFA */
1133
1134         [StructLayout(LayoutKind.Sequential)]
1135         public struct TestStruct5 {
1136                 public float d1, d2;
1137         }
1138         
1139         [DllImport ("libtest", EntryPoint="mono_test_marshal_ia64_pass_return_struct5")]
1140         public static extern TestStruct5 mono_test_marshal_ia64_pass_return_struct5 (double d1, double d2, TestStruct5 s, int i, double f3, double f4);
1141
1142         public static int test_0_ia64_struct5 () {
1143                 TestStruct5 s = new TestStruct5 ();
1144                 s.d1 = 5.0f;
1145                 s.d2 = -5.0f;
1146
1147                 TestStruct5 s2 = mono_test_marshal_ia64_pass_return_struct5 (1.0, 2.0, s, 5, 3.0, 4.0);
1148
1149                 return (s2.d1 == 13.0 && s2.d2 == 7.0) ? 0 : 1;
1150         }
1151
1152         /* Test 6: Double HFA */
1153
1154         [StructLayout(LayoutKind.Sequential)]
1155         public struct TestStruct6 {
1156                 public double d1, d2;
1157         }
1158         
1159         [DllImport ("libtest", EntryPoint="mono_test_marshal_ia64_pass_return_struct6")]
1160         public static extern TestStruct6 mono_test_marshal_ia64_pass_return_struct6 (double d1, double d2, TestStruct6 s, int i, double f3, double f4);
1161
1162         public static int test_0_ia64_struct6 () {
1163                 TestStruct6 s = new TestStruct6 ();
1164                 s.d1 = 6.0;
1165                 s.d2 = -6.0;
1166
1167                 TestStruct6 s2 = mono_test_marshal_ia64_pass_return_struct6 (1.0, 2.0, s, 3, 4.0, 5.0);
1168
1169                 return (s2.d1 == 12.0 && s2.d2 == 3.0) ? 0 : 1;
1170         }
1171         
1172         /* Blittable class */
1173         [DllImport("libtest")]
1174         private static extern BlittableClass TestBlittableClass (BlittableClass vl);
1175
1176         public static int test_0_marshal_blittable_class () {
1177                 BlittableClass v1 = new BlittableClass ();
1178
1179                 /* Since it is blittable, it looks like it is passed as in/out */
1180                 BlittableClass v2 = TestBlittableClass (v1);
1181
1182                 if (v1.a != 2 || v1.b != 3)
1183                         return 1;
1184                 
1185                 if (v2.a != 2 || v2.b != 3)
1186                         return 2;
1187
1188                 // Test null
1189                 BlittableClass v3 = TestBlittableClass (null);
1190
1191                 if (v3.a != 42 || v3.b != 43)
1192                         return 3;
1193                 
1194                 return 0;
1195         }
1196
1197         /*
1198          * Generic structures
1199          */
1200
1201         [StructLayout(LayoutKind.Sequential)]
1202         public struct Amd64Struct1Gen<T> {
1203                 public T i;
1204                 public T j;
1205                 public T k;
1206                 public T l;
1207         }
1208         
1209         [DllImport ("libtest", EntryPoint="mono_test_marshal_amd64_pass_return_struct1")]
1210         public static extern Amd64Struct1Gen<int> mono_test_marshal_amd64_pass_return_struct1_gen (Amd64Struct1Gen<int> s);
1211
1212         public static int test_0_amd64_struct1_gen () {
1213                 Amd64Struct1Gen<int> s = new Amd64Struct1Gen<int> ();
1214                 s.i = 5;
1215                 s.j = -5;
1216                 s.k = 0xffffff;
1217                 s.l = 0xfffffff;
1218
1219                 Amd64Struct1Gen<int> s2 = mono_test_marshal_amd64_pass_return_struct1_gen (s);
1220
1221                 return ((s2.i == 6) && (s2.j == -4) && (s2.k == 0x1000000) && (s2.l == 0x10000000)) ? 0 : 1;
1222         }
1223
1224         /*
1225          * Other tests
1226          */
1227
1228         public static int test_0_marshal_byval_class () {
1229                 SimpleObj obj0 = new SimpleObj ();
1230                 obj0.str = "T1";
1231                 obj0.i = 4;
1232                 
1233                 if (class_marshal_test0 (obj0) != 0)
1234                         return 1;
1235
1236                 return 0;
1237         }
1238
1239         public static int test_0_marshal_byval_class_null () {
1240                 if (class_marshal_test4 (null) != 0)
1241                         return 1;
1242
1243                 return 0;
1244         }
1245
1246         public static int test_0_marshal_out_class () {
1247                 SimpleObj obj1;
1248
1249                 class_marshal_test1 (out obj1);
1250
1251                 if (obj1.str != "ABC")
1252                         return 1;
1253
1254                 if (obj1.i != 5)
1255                         return 2;
1256
1257                 return 0;
1258         }
1259
1260         public static int test_0_marshal_string () {
1261                 return string_marshal_test0 ("TEST0");
1262         }
1263
1264         public static int test_0_marshal_out_string () {
1265                 string res;
1266                 
1267                 string_marshal_test1 (out res);
1268
1269                 if (res != "TEST1")
1270                         return 1;
1271
1272                 return 0;
1273         }
1274
1275         public static int test_0_marshal_byref_string () {
1276                 string res = "TEST1";
1277
1278                 return string_marshal_test2 (ref res);
1279         }
1280
1281         public static int test_0_marshal_null_string () {
1282                 return string_marshal_test3 (null);
1283         }
1284
1285         [DllImport ("libtest", EntryPoint="mono_test_stdcall_name_mangling", CallingConvention=CallingConvention.StdCall)]
1286         public static extern int mono_test_stdcall_name_mangling (int a, int b, int c);
1287
1288         public static int test_0_stdcall_name_mangling () {
1289                 return mono_test_stdcall_name_mangling (0, 1, 2) == 3 ? 0 : 1;
1290         }
1291
1292         /* Float test */
1293
1294         [DllImport ("libtest", EntryPoint="mono_test_marshal_pass_return_float")]
1295         public static extern float mono_test_marshal_pass_return_float (float f);
1296
1297         public static int test_0_pass_return_float () {
1298                 float f = mono_test_marshal_pass_return_float (1.5f);
1299
1300                 return (f == 2.5f) ? 0 : 1;
1301         }
1302
1303         /*
1304          * Pointers to structures can not be passed
1305          */
1306
1307         /* This seems to be allowed by MS in some cases */
1308         /*
1309         public struct CharInfo {
1310                 public char Character;
1311                 public short Attributes;
1312         }
1313
1314         [DllImport ("libtest", EntryPoint="mono_test_marshal_struct")]
1315         public static unsafe extern int mono_test_marshal_ptr_to_struct (CharInfo *ptr);
1316
1317         public static unsafe int test_0_marshal_ptr_to_struct () {
1318                 CharInfo [] buffer = new CharInfo [1];
1319                 fixed (CharInfo *ptr = &buffer [0]) {
1320                         try {
1321                                 mono_test_marshal_ptr_to_struct (ptr);
1322                                 return 1;
1323                         }
1324                         catch (MarshalDirectiveException) {
1325                                 return 0;
1326                         }
1327                 }
1328                 return 1;
1329         }
1330         */
1331
1332         /*
1333          * LPWStr marshalling
1334          */
1335
1336         [DllImport("libtest", EntryPoint="test_lpwstr_marshal")]
1337         [return: MarshalAs(UnmanagedType.LPWStr)]
1338         private static extern string mono_test_marshal_lpwstr_marshal(
1339                 [MarshalAs(UnmanagedType.LPWStr)] string s,
1340                 int length );
1341
1342         [DllImport("libtest", EntryPoint="test_lpwstr_marshal", CharSet=CharSet.Unicode)]
1343         private static extern string mono_test_marshal_lpwstr_marshal2(
1344                 string s,
1345                 int length );
1346
1347         [DllImport("libtest", EntryPoint="test_lpwstr_marshal_out")]
1348         private static extern void mono_test_marshal_lpwstr_out_marshal(
1349                 [MarshalAs(UnmanagedType.LPWStr)] out string s);
1350
1351         [DllImport("libtest", EntryPoint="test_lpwstr_marshal_out", CharSet=CharSet.Unicode)]
1352         private static extern void mono_test_marshal_lpwstr_out_marshal2(
1353                 out string s);
1354
1355         public static int test_0_pass_return_lwpstr () {
1356                 string s;
1357                 
1358                 mono_test_marshal_lpwstr_out_marshal (out s);
1359
1360                 if (s != "ABC")
1361                         return 1;
1362
1363                 s = null;
1364                 mono_test_marshal_lpwstr_out_marshal2 (out s);
1365
1366                 if (s != "ABC")
1367                         return 2;
1368                 
1369                 return 0;               
1370         }
1371
1372         public static int test_0_out_lwpstr () {
1373                 string s = "ABC";
1374                 
1375                 string res = mono_test_marshal_lpwstr_marshal (s, s.Length);
1376
1377                 if (res != "ABC")
1378                         return 1;
1379
1380                 string res2 = mono_test_marshal_lpwstr_marshal2 (s, s.Length);
1381
1382                 if (res2 != "ABC")
1383                         return 2;
1384                 
1385                 return 0;               
1386         }
1387
1388         /*
1389          * Byref bool marshalling
1390          */
1391
1392         [DllImport("libtest")]
1393         extern static int marshal_test_ref_bool
1394         (
1395                 int i, 
1396                 [MarshalAs(UnmanagedType.I1)] ref bool b1, 
1397                 [MarshalAs(UnmanagedType.VariantBool)] ref bool b2, 
1398                 ref bool b3
1399         );
1400
1401         public static int test_0_pass_byref_bool () {
1402                 for (int i = 0; i < 8; i++)
1403                 {
1404                         bool b1 = (i & 4) != 0;
1405                         bool b2 = (i & 2) != 0;
1406                         bool b3 = (i & 1) != 0;
1407                         bool orig_b1 = b1, orig_b2 = b2, orig_b3 = b3;
1408                         if (marshal_test_ref_bool(i, ref b1, ref b2, ref b3) != 0)
1409                                 return 4 * i + 1;
1410                         if (b1 != !orig_b1)
1411                                 return 4 * i + 2;
1412                         if (b2 != !orig_b2)
1413                                 return 4 * i + 3;
1414                         if (b3 != !orig_b3)
1415                                 return 4 * i + 4;
1416                 }
1417
1418                 return 0;
1419         }
1420
1421         /*
1422          * Bool struct field marshalling
1423          */
1424
1425         struct BoolStruct
1426         {
1427                 public int i;
1428                 [MarshalAs(UnmanagedType.I1)] public bool b1;
1429                 [MarshalAs(UnmanagedType.VariantBool)] public bool b2;
1430                 public bool b3;
1431         }
1432
1433         [DllImport("libtest")]
1434         extern static int marshal_test_bool_struct(ref BoolStruct s);
1435
1436         public static int test_0_pass_bool_in_struct () {
1437                 for (int i = 0; i < 8; i++)
1438                 {
1439                         BoolStruct s = new BoolStruct();
1440                         s.i = i;
1441                         s.b1 = (i & 4) != 0;
1442                         s.b2 = (i & 2) != 0;
1443                         s.b3 = (i & 1) != 0;
1444                         BoolStruct orig = s;
1445                         if (marshal_test_bool_struct(ref s) != 0)
1446                                 return 4 * i + 33;
1447                         if (s.b1 != !orig.b1)
1448                                 return 4 * i + 34;
1449                         if (s.b2 != !orig.b2)
1450                                 return 4 * i + 35;
1451                         if (s.b3 != !orig.b3)
1452                                 return 4 * i + 36;
1453                 }
1454
1455                 return 0;
1456         }
1457
1458         /*
1459          * Alignment of structs containing longs
1460          */
1461
1462         struct LongStruct2 {
1463                 public long l;
1464         }
1465
1466         struct LongStruct {
1467                 public int i;
1468                 public LongStruct2 l;
1469         }
1470
1471         [DllImport("libtest")]
1472         extern static int mono_test_marshal_long_struct (ref LongStruct s);
1473
1474         public static int test_47_pass_long_struct () {
1475                 LongStruct s = new LongStruct ();
1476                 s.i = 5;
1477                 s.l = new LongStruct2 ();
1478                 s.l.l = 42;
1479
1480                 return mono_test_marshal_long_struct (ref s);
1481         }
1482
1483         /*
1484          * Invoking pinvoke methods through delegates
1485          */
1486
1487         delegate int MyDelegate (string name);
1488
1489         [DllImport ("libtest", EntryPoint="mono_test_puts_static")]
1490         public static extern int puts_static (string name);
1491
1492         public static int test_0_invoke_pinvoke_through_delegate () {
1493                 puts_static ("A simple Test for PInvoke 1");
1494
1495                 MyDelegate d = new MyDelegate (puts_static);
1496                 d ("A simple Test for PInvoke 2");
1497
1498                 object [] args = {"A simple Test for PInvoke 3"};
1499                 d.DynamicInvoke (args);
1500
1501                 return 0;
1502         }
1503
1504         /*
1505          * Missing virtual pinvoke methods
1506          */
1507
1508         public class T {
1509
1510                 public virtual object MyClone ()
1511                 {
1512                         return null;
1513                 }
1514         }
1515
1516         public class T2 : T {
1517                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1518                 public override extern object MyClone ();
1519         }
1520
1521         public static int test_0_missing_virtual_pinvoke_method () {
1522                 T2 t = new T2 ();
1523
1524                 try {
1525                         t.MyClone ();
1526                 } catch (Exception ex) {
1527                         return 0;
1528                 }
1529                 
1530                 return 1;
1531         }
1532
1533         /*
1534          * Marshalling of type 'object'
1535          */
1536
1537         [DllImport ("libtest", EntryPoint="mono_test_marshal_class")]
1538         public static extern SimpleClass mono_test_marshal_object (int i, int j, int k, object ss, int l);
1539
1540         public static int test_0_marshal_object () {
1541                 try {
1542                         mono_test_marshal_object (0, 0, 0, null, 0);
1543                         return 1;
1544                 } catch (Exception) {
1545                         return 0;
1546                 }
1547         }
1548
1549         /*
1550          * Marshalling of DateTime to OLE DATE (double)
1551          */
1552         [DllImport ("libtest", EntryPoint="mono_test_marshal_date_time")]
1553         public static extern double mono_test_marshal_date_time (DateTime d, out DateTime d2);
1554
1555         public static int test_0_marshal_date_time () {
1556                 DateTime d = new DateTime (2009, 12, 6);
1557                 DateTime d2;
1558                 double d3 = mono_test_marshal_date_time (d, out d2);
1559                 if (d3 != 40153.0)
1560                         return 1;
1561                 if (d2 != d)
1562                         return 2;
1563                 return 0;
1564         }
1565
1566         /*
1567          * Calling pinvoke functions dynamically using calli
1568          */
1569         
1570         [DllImport("libtest")]
1571         private static extern IntPtr mono_test_marshal_lookup_symbol (string fileName);
1572
1573         delegate void CalliDel (IntPtr a, int[] f);
1574
1575         public static int test_0_calli_dynamic () {
1576                 /* we need the cdecl version because the icall convention demands it under Windows */
1577                 IntPtr func = mono_test_marshal_lookup_symbol ("mono_test_marshal_inout_array_cdecl");
1578
1579                 DynamicMethod dm = new DynamicMethod ("calli", typeof (void), new Type [] { typeof (IntPtr), typeof (int[]) });
1580
1581                 var il = dm.GetILGenerator ();
1582                 var signature = SignatureHelper.GetMethodSigHelper (CallingConvention.Cdecl, typeof (void));
1583
1584                 il.Emit (OpCodes.Ldarg, 1);
1585                 signature.AddArgument (typeof (byte[]));
1586
1587                 il.Emit (OpCodes.Ldarg_0);
1588
1589                 il.Emit (OpCodes.Calli, signature);
1590                 il.Emit (OpCodes.Ret);
1591
1592                 var f = (CalliDel)dm.CreateDelegate (typeof (CalliDel));
1593
1594                 int[] arr = new int [1000];
1595                 for (int i = 0; i < 50; ++i)
1596                         arr [i] = (int)i;
1597                 f (func, arr);
1598                 if (arr.Length != 1000)
1599                         return 1;
1600                 for (int i = 0; i < 50; ++i)
1601                         if (arr [i] != 50 - i)
1602                                 return 2;
1603
1604                 return 0;
1605         }
1606
1607
1608         /*char array marshaling */
1609         [DllImport ("libtest", EntryPoint="mono_test_marshal_ansi_char_array", CharSet=CharSet.Ansi)]
1610         public static extern int mono_test_marshal_ansi_char_array (char[] a1);
1611
1612         public static int test_0_marshal_ansi_char_array () {
1613                 char[] buf = new char [32];
1614                 buf [0] = 'q';
1615                 buf [1] = 'w';
1616                 buf [2] = 'e';
1617                 buf [3] = 'r';
1618
1619                 if (mono_test_marshal_ansi_char_array (buf) != 0)
1620                         return 1;
1621
1622                 string s = new string (buf);
1623                 if (s.StartsWith ("qwer"))
1624                         return 0;
1625                 else
1626                         return 2;
1627         }
1628
1629         /*char array marshaling */
1630         [DllImport ("libtest", EntryPoint="mono_test_marshal_unicode_char_array", CharSet=CharSet.Unicode)]
1631         public static extern int mono_test_marshal_unicode_char_array (char[] a1);
1632
1633         public static int test_0_marshal_unicode_char_array () {
1634                 char[] buf = new char [32];
1635                 buf [0] = 'q';
1636                 buf [1] = 'w';
1637                 buf [2] = 'e';
1638                 buf [3] = 'r';
1639
1640                 if (mono_test_marshal_unicode_char_array (buf) != 0)
1641                         return 1;
1642
1643                 string s = new string (buf);
1644                 if (s.StartsWith ("abcdef"))
1645                         return 0;
1646                 else
1647                         return 2;
1648         }
1649
1650         [DllImport ("libtest", EntryPoint="mono_test_marshal_lpstr")]
1651         public static extern int mono_test_marshal_lpstr ([MarshalAs(UnmanagedType.LPStr)] string str);
1652
1653         public static int test_0_mono_test_marshal_lpstr () {
1654                 string str = "ABC";
1655
1656                 if (mono_test_marshal_lpstr (str) != 0)
1657                         return 1;
1658
1659                 return 0;
1660         }
1661
1662         [DllImport ("libtest", EntryPoint="mono_test_marshal_lpwstr")]
1663         public static extern int mono_test_marshal_lpwstr ([MarshalAs(UnmanagedType.LPWStr)] string str);
1664
1665         public static int test_0_mono_test_marshal_lpwstr () {
1666                 string str = "ABC";
1667
1668                 if (mono_test_marshal_lpwstr (str) != 0)
1669                         return 1;
1670
1671                 return 0;
1672         }
1673
1674
1675         [method: DllImport ("libtest", EntryPoint="mono_test_marshal_return_lpstr")]
1676         [return: MarshalAs(UnmanagedType.LPStr)]
1677         public static extern string mono_test_marshal_return_lpstr ();
1678
1679         public static int test_0_mono_test_marshal_return_lpstr () {
1680                 string str = mono_test_marshal_return_lpstr ();
1681                 if ("XYZ" == str)
1682                         return 0;
1683
1684                 return 1;
1685         }
1686
1687         [method: DllImport ("libtest", EntryPoint="mono_test_marshal_return_lpwstr")]
1688         [return: MarshalAs(UnmanagedType.LPWStr)]
1689         public static extern string mono_test_marshal_return_lpwstr ();
1690
1691         public static int test_0_mono_test_marshal_return_lpwstr () {
1692                 string str = mono_test_marshal_return_lpwstr ();
1693                 if ("XYZ" == str)
1694                         return 0;
1695
1696                 return 1;
1697         }
1698
1699 }
1700