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