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