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