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