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