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