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