2007-06-12 Zoltan Varga <vargaz@gmail.com>
[mono.git] / mono / tests / pinvoke2.cs
1 using System;
2 using System.Text;
3 using System.Runtime.InteropServices;
4 using System.Runtime.CompilerServices;
5
6 public class Tests {
7
8         public int int_field;
9
10         public static int delegate_test (int a)
11         {
12                 if (a == 2)
13                         return 0;
14
15                 return 1;
16         }
17
18         public int delegate_test_instance (int a)
19         {
20                 return int_field + a;
21         }
22         
23         [StructLayout (LayoutKind.Sequential)]
24         public struct SimpleStruct {
25                 public bool a;
26                 public bool b;
27                 public bool c;
28                 public string d;
29                 [MarshalAs(UnmanagedType.LPWStr)]
30                 public string d2;
31         }
32
33         [StructLayout (LayoutKind.Sequential)]
34         public struct SimpleStruct2 {
35                 public bool a;
36                 public bool b;
37                 public bool c;
38                 public string d;
39                 public byte e;
40                 public double f;
41                 public byte g;
42                 public long h;
43         }
44
45         [StructLayout (LayoutKind.Sequential, Size=0)]
46         public struct EmptyStruct {
47         }
48
49         [StructLayout (LayoutKind.Sequential)]
50         public struct DelegateStruct {
51                 public int a;
52                 public SimpleDelegate del;
53                 [MarshalAs(UnmanagedType.FunctionPtr)] 
54                 public SimpleDelegate del2;
55         }
56
57         /* sparcv9 has complex conventions when passing structs with doubles in them 
58            by value, some simple tests for them */
59         [StructLayout (LayoutKind.Sequential)]
60         public struct Point {
61                 public double x;
62                 public double y;
63         }
64
65         [StructLayout (LayoutKind.Sequential)]
66         public struct MixedPoint {
67                 public int x;
68                 public double y;
69         }
70
71         [StructLayout (LayoutKind.Sequential)]
72         public class SimpleClass {
73                 public bool a;
74                 public bool b;
75                 public bool c;
76                 public string d;
77                 public byte e;
78                 public double f;
79                 public byte g;
80                 public long h;
81         }
82
83         [StructLayout (LayoutKind.Sequential)]
84         public class EmptyClass {
85         }
86
87         [StructLayout (LayoutKind.Sequential)]
88         public struct LongAlignStruct {
89                 public int a;
90                 public long b;
91                 public long c;
92         }
93
94         [StructLayout(LayoutKind.Sequential)]
95         public class BlittableClass
96         {
97                 public int a = 1;
98                 public int b = 2;
99         }
100
101         [StructLayout (LayoutKind.Sequential)]
102         class SimpleObj
103         {
104                 public string str;
105                 public int i;
106         }
107
108         [StructLayout(LayoutKind.Sequential)]
109         struct AsAnyStruct
110         {
111                 public int i;
112                 public int j;
113                 public int k;
114                 public String s;
115
116                 public AsAnyStruct(int i, int j, int k, String s) {
117                         this.i = i;
118                         this.j = j;
119                         this.k = k;
120                         this.s = s;
121                 }
122         }
123
124         [StructLayout(LayoutKind.Sequential)]
125         class AsAnyClass
126         {
127                 public int i;
128                 public int j;
129                 public int k;
130                 public String s;
131
132                 public AsAnyClass(int i, int j, int k, String s) {
133                         this.i = i;
134                         this.j = j;
135                         this.k = k;
136                 }
137         }
138
139         [DllImport ("libnot-found", EntryPoint="not_found")]
140         public static extern int mono_library_not_found ();
141
142         [DllImport ("libtest", EntryPoint="not_found")]
143         public static extern int mono_entry_point_not_found ();
144
145         [DllImport ("libtest.dll", EntryPoint="mono_test_marshal_char")]
146         public static extern int mono_test_marshal_char_2 (char a1);
147
148         [DllImport ("test", EntryPoint="mono_test_marshal_char")]
149         public static extern int mono_test_marshal_char_3 (char a1);
150
151         [DllImport ("libtest", EntryPoint="mono_test_marshal_char")]
152         public static extern int mono_test_marshal_char (char a1);
153
154         [DllImport ("libtest", EntryPoint="mono_test_marshal_char_array", CharSet=CharSet.Unicode)]
155         public static extern int mono_test_marshal_char_array (char[] a1);
156
157         [DllImport ("libtest", EntryPoint="mono_test_marshal_bool_byref")]
158         public static extern int mono_test_marshal_bool_byref (int a, ref bool b, int c);
159
160         [DllImport ("libtest", EntryPoint="mono_test_marshal_array")]
161         public static extern int mono_test_marshal_array (int [] a1);
162
163         [DllImport ("libtest", EntryPoint="mono_test_marshal_empty_string_array")]
164         public static extern int mono_test_marshal_empty_string_array (string [] a1);
165
166         [DllImport ("libtest", EntryPoint="mono_test_marshal_string_array")]
167         public static extern int mono_test_marshal_string_array (string [] a1);
168
169         [DllImport ("libtest", EntryPoint="mono_test_marshal_unicode_string_array", CharSet=CharSet.Unicode)]
170         public static extern int mono_test_marshal_unicode_string_array (string [] a1, [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.LPStr)]string [] a2);
171
172         [DllImport ("libtest", EntryPoint="mono_test_marshal_stringbuilder_array")]
173         public static extern int mono_test_marshal_stringbuilder_array (StringBuilder [] a1);   
174
175         [DllImport ("libtest", EntryPoint="mono_test_marshal_inout_array")]
176         public static extern int mono_test_marshal_inout_array ([In, Out] int [] a1);
177
178         [DllImport ("libtest", EntryPoint="mono_test_marshal_out_array")]
179         public static extern int mono_test_marshal_out_array ([Out] [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] int [] a1, int n);
180
181         [DllImport ("libtest", EntryPoint="mono_test_marshal_inout_nonblittable_array", CharSet = CharSet.Unicode)]
182         public static extern int mono_test_marshal_inout_nonblittable_array ([In, Out] char [] a1);
183         
184         [DllImport ("libtest", EntryPoint="mono_test_marshal_struct")]
185         public static extern int mono_test_marshal_struct (SimpleStruct ss);
186
187         [DllImport ("libtest", EntryPoint="mono_test_marshal_struct2")]
188         public static extern int mono_test_marshal_struct2 (SimpleStruct2 ss);
189
190         [DllImport ("libtest", EntryPoint="mono_test_marshal_struct2_2")]
191         public static extern int mono_test_marshal_struct2_2 (int i, int j, int k, SimpleStruct2 ss);
192
193         [DllImport ("libtest", EntryPoint="mono_test_marshal_byref_struct")]
194         public static extern int mono_test_marshal_byref_struct (ref SimpleStruct ss, bool a, bool b, bool c, String d);
195
196         [DllImport ("libtest", EntryPoint="mono_test_marshal_byref_struct")]
197         public static extern int mono_test_marshal_byref_struct_in ([In] ref SimpleStruct ss, bool a, bool b, bool c, String d);
198
199         [DllImport ("libtest", EntryPoint="mono_test_marshal_byref_struct")]
200         public static extern int mono_test_marshal_byref_struct_inout ([In, Out] ref SimpleStruct ss, bool a, bool b, bool c, String d);
201
202         [DllImport ("libtest", EntryPoint="mono_test_marshal_point")]
203         public static extern int mono_test_marshal_point (Point p);
204
205         [DllImport ("libtest", EntryPoint="mono_test_marshal_mixed_point")]
206         public static extern int mono_test_marshal_mixed_point (MixedPoint p);
207
208         [DllImport ("libtest", EntryPoint="mono_test_empty_struct")]
209         public static extern int mono_test_empty_struct (int a, EmptyStruct es, int b);
210
211         [DllImport ("libtest", EntryPoint="mono_test_marshal_lpstruct")]
212         public static extern int mono_test_marshal_lpstruct ([In, MarshalAs(UnmanagedType.LPStruct)] SimpleStruct ss);
213
214         [DllImport ("libtest", EntryPoint="mono_test_marshal_lpstruct_blittable")]
215         public static extern int mono_test_marshal_lpstruct_blittable ([In, MarshalAs(UnmanagedType.LPStruct)] Point p);
216
217         [DllImport ("libtest", EntryPoint="mono_test_marshal_struct_array")]
218         public static extern int mono_test_marshal_struct_array (SimpleStruct2[] ss);
219
220         [DllImport ("libtest", EntryPoint="mono_test_marshal_long_align_struct_array")]
221         public static extern int mono_test_marshal_long_align_struct_array (LongAlignStruct[] ss);
222
223         [DllImport ("libtest", EntryPoint="mono_test_marshal_class")]
224         public static extern SimpleClass mono_test_marshal_class (int i, int j, int k, SimpleClass ss, int l);
225
226         [DllImport ("libtest", EntryPoint="mono_test_marshal_byref_class")]
227         public static extern int mono_test_marshal_byref_class (ref SimpleClass ss);
228
229         [DllImport ("libtest", EntryPoint="mono_test_marshal_delegate")]
230         public static extern int mono_test_marshal_delegate (SimpleDelegate d);
231
232         [DllImport ("libtest", EntryPoint="mono_test_marshal_delegate_struct")]
233         public static extern DelegateStruct mono_test_marshal_delegate_struct (DelegateStruct d);
234
235         [DllImport ("libtest", EntryPoint="mono_test_marshal_return_delegate")]
236         public static extern SimpleDelegate mono_test_marshal_return_delegate (SimpleDelegate d);
237
238         [DllImport ("libtest", EntryPoint="mono_test_return_vtype")]
239         public static extern SimpleStruct mono_test_return_vtype (IntPtr i);
240
241         [DllImport ("libtest", EntryPoint="mono_test_marshal_stringbuilder")]
242         public static extern void mono_test_marshal_stringbuilder (StringBuilder sb, int len);
243
244         [DllImport ("libtest", EntryPoint="mono_test_marshal_stringbuilder_default")]
245         public static extern void mono_test_marshal_stringbuilder_default (StringBuilder sb, int len);
246
247         [DllImport ("libtest", EntryPoint="mono_test_marshal_stringbuilder_unicode", CharSet=CharSet.Unicode)]
248         public static extern void mono_test_marshal_stringbuilder_unicode (StringBuilder sb, int len);
249
250         [DllImport ("libtest", EntryPoint="mono_test_last_error", SetLastError=true)]
251         public static extern void mono_test_last_error (int err);
252
253         [DllImport ("libtest", EntryPoint="mono_test_asany")]
254         public static extern int mono_test_asany ([MarshalAs (UnmanagedType.AsAny)] object o, int what);
255
256         [DllImport ("libtest", EntryPoint="mono_test_asany", CharSet=CharSet.Unicode)]
257         public static extern int mono_test_asany_unicode ([MarshalAs (UnmanagedType.AsAny)] object o, int what);
258
259         [DllImport("libtest", EntryPoint="mono_test_marshal_asany_in")]
260         static extern void mono_test_asany_in ([MarshalAs(UnmanagedType.AsAny)][In] object obj); 
261
262         [DllImport("libtest", EntryPoint="mono_test_marshal_asany_out")]
263         static extern void mono_test_asany_out ([MarshalAs(UnmanagedType.AsAny)][Out] object obj); 
264         [DllImport("libtest", EntryPoint="mono_test_marshal_asany_inout")]
265         static extern void mono_test_asany_inout ([MarshalAs(UnmanagedType.AsAny)][In, Out] object obj); 
266
267         [DllImport ("libtest")]
268         static extern int class_marshal_test0 (SimpleObj obj);
269
270         [DllImport ("libtest")]
271         static extern void class_marshal_test1 (out SimpleObj obj);
272
273         [DllImport ("libtest")]
274         static extern int class_marshal_test4 (SimpleObj obj);
275         
276         [DllImport ("libtest")]
277         static extern int string_marshal_test0 (string str);
278
279         [DllImport ("libtest")]
280         static extern void string_marshal_test1 (out string str);
281
282         [DllImport ("libtest")]
283         static extern int string_marshal_test2 (ref string str);
284
285         [DllImport ("libtest")]
286         static extern int string_marshal_test3 (string str);
287
288         public delegate int SimpleDelegate (int a);
289
290         public static int Main (string[] args) {
291                 return TestDriver.RunTests (typeof (Tests), args);
292         }
293
294         public static int test_0_marshal_char () {
295                 return mono_test_marshal_char ('a');
296         }
297
298         public static int test_0_marshal_char_array () {
299                 // a unicode char[] is implicitly marshalled as [Out]
300                 char[] buf = new char [32];
301                 mono_test_marshal_char_array (buf);
302                 string s = new string (buf);
303                 if (s.StartsWith ("abcdef"))
304                         return 0;
305                 else
306                         return 1;
307         }
308
309         public static int test_1225_marshal_array () {
310                 int [] a1 = new int [50];
311                 for (int i = 0; i < 50; i++)
312                         a1 [i] = i;
313
314                 return mono_test_marshal_array (a1);
315         }
316
317         public static int test_1225_marshal_inout_array () {
318                 int [] a1 = new int [50];
319                 for (int i = 0; i < 50; i++)
320                         a1 [i] = i;
321
322                 int res = mono_test_marshal_inout_array (a1);
323
324                 for (int i = 0; i < 50; i++)
325                         if (a1 [i] != 50 - i) {
326                                 Console.WriteLine ("X: " + i + " " + a1 [i]);
327                                 return 2;
328                         }
329
330                 return res;
331         }
332
333         public static int test_0_marshal_out_array () {
334                 int [] a1 = new int [50];
335
336                 int res = mono_test_marshal_out_array (a1, 0);
337
338                 for (int i = 0; i < 50; i++)
339                         if (a1 [i] != i) {
340                                 Console.WriteLine ("X: " + i + " " + a1 [i]);
341                                 return 2;
342                         }
343
344                 return 0;
345         }
346
347         public static int test_0_marshal_inout_nonblittable_array () {
348                 char [] a1 = new char [10];
349                 for (int i = 0; i < 10; i++)
350                         a1 [i] = "Hello, World" [i];
351
352                 int res = mono_test_marshal_inout_nonblittable_array (a1);
353
354                 for (int i = 0; i < 10; i++)
355                         if (a1 [i] != 'F')
356                                 return 2;
357
358                 return res;
359         }
360
361         public static int test_0_marshal_struct () {
362                 SimpleStruct ss = new  SimpleStruct ();
363                 ss.b = true;
364                 ss.d = "TEST";
365                 
366                 return mono_test_marshal_struct (ss);
367         }
368
369         public static int test_0_marshal_struct2 () {
370                 SimpleStruct2 ss2 = new  SimpleStruct2 ();
371                 ss2.b = true;
372                 ss2.d = "TEST";
373                 ss2.e = 99;
374                 ss2.f = 1.5;
375                 ss2.g = 42;
376                 ss2.h = 123L;
377
378                 return mono_test_marshal_struct2 (ss2);
379         }
380
381         public static int test_0_marshal_struct3 () {
382                 SimpleStruct2 ss2 = new  SimpleStruct2 ();
383                 ss2.b = true;
384                 ss2.d = "TEST";
385                 ss2.e = 99;
386                 ss2.f = 1.5;
387                 ss2.g = 42;
388                 ss2.h = 123L;
389
390                 return mono_test_marshal_struct2_2 (10, 11, 12, ss2);
391         }
392
393         public static int test_0_marshal_empty_struct () {
394                 EmptyStruct es = new EmptyStruct ();
395
396                 if (mono_test_empty_struct (1, es, 2) != 0)
397                         return 1;
398                 
399                 return 0;
400         }
401
402         public static int test_0_marshal_lpstruct () {
403                 SimpleStruct ss = new  SimpleStruct ();
404                 ss.b = true;
405                 ss.d = "TEST";
406                 
407                 return mono_test_marshal_lpstruct (ss);
408         }
409
410         public static int test_0_marshal_lpstruct_blittable () {
411                 Point p = new Point ();
412                 p.x = 1.0;
413                 p.y = 2.0;
414                 
415                 return mono_test_marshal_lpstruct_blittable (p);
416         }
417
418         public static int test_0_marshal_struct_array () {
419                 SimpleStruct2[] ss_arr = new SimpleStruct2 [2];
420
421                 SimpleStruct2 ss2 = new SimpleStruct2 ();
422                 ss2.b = true;
423                 ss2.d = "TEST";
424                 ss2.e = 99;
425                 ss2.f = 1.5;
426                 ss2.g = 42;
427                 ss2.h = 123L;
428
429                 ss_arr [0] = ss2;
430
431                 ss2.b = false;
432                 ss2.d = "TEST2";
433                 ss2.e = 100;
434                 ss2.f = 2.5;
435                 ss2.g = 43;
436                 ss2.h = 124L;
437
438                 ss_arr [1] = ss2;
439
440                 return mono_test_marshal_struct_array (ss_arr);
441         }
442
443         public static int test_105_marshal_long_align_struct_array () {
444                 LongAlignStruct[] ss_arr = new LongAlignStruct [2];
445
446                 LongAlignStruct ss = new LongAlignStruct ();
447                 ss.a = 5;
448                 ss.b = 10;
449                 ss.c = 15;
450
451                 ss_arr [0] = ss;
452
453                 ss.a = 20;
454                 ss.b = 25;
455                 ss.c = 30;
456
457                 ss_arr [1] = ss;
458
459                 return mono_test_marshal_long_align_struct_array (ss_arr);
460         }
461
462         /* Test classes as arguments and return values */
463         public static int test_0_marshal_class () {
464                 SimpleClass ss = new  SimpleClass ();
465                 ss.b = true;
466                 ss.d = "TEST";
467                 ss.e = 99;
468                 ss.f = 1.5;
469                 ss.g = 42;
470                 ss.h = 123L;
471
472                 SimpleClass res = mono_test_marshal_class (10, 11, 12, ss, 14);
473                 if (res == null)
474                         return 1;
475                 if  (! (res.a == ss.a && res.b == ss.b && res.c == ss.c && 
476                                 res.d == ss.d && res.e == ss.e && res.f == ss.f &&
477                                 res.g == ss.g && res.h == ss.h))
478                         return 2;
479
480                 /* Test null arguments and results */
481                 res = mono_test_marshal_class (10, 11, 12, null, 14);
482                 if (res != null)
483                         return 3;
484
485                 return 0;
486         }
487
488         public static int test_0_marshal_byref_class () {
489                 SimpleClass ss = new  SimpleClass ();
490                 ss.b = true;
491                 ss.d = "TEST";
492                 ss.e = 99;
493                 ss.f = 1.5;
494                 ss.g = 42;
495                 ss.h = 123L;
496
497                 int res = mono_test_marshal_byref_class (ref ss);
498                 if (ss.d != "TEST-RES")
499                         return 1;
500
501                 return 0;
502         }
503
504         public static int test_0_marshal_delegate () {
505                 SimpleDelegate d = new SimpleDelegate (delegate_test);
506
507                 return mono_test_marshal_delegate (d);
508         }
509
510         public static int test_34_marshal_instance_delegate () {
511                 Tests t = new Tests ();
512                 t.int_field = 32;
513                 SimpleDelegate d = new SimpleDelegate (t.delegate_test_instance);
514
515                 return mono_test_marshal_delegate (d);
516         }
517
518         public static int test_0_marshal_return_delegate () {
519                 SimpleDelegate d = new SimpleDelegate (delegate_test);
520
521                 SimpleDelegate d2 = mono_test_marshal_return_delegate (d);
522
523                 return d2 (2);
524         }
525
526         public static int test_0_marshal_delegate_struct () {
527                 DelegateStruct s = new DelegateStruct ();
528
529                 s.a = 2;
530                 s.del = new SimpleDelegate (delegate_test);
531                 s.del2 = new SimpleDelegate (delegate_test);
532
533                 DelegateStruct res = mono_test_marshal_delegate_struct (s);
534
535                 if (res.a != 0)
536                         return 1;
537                 if (res.del (2) != 0)
538                         return 2;
539                 if (res.del2 (2) != 0)
540                         return 3;
541
542                 return 0;
543         }
544
545         public static int test_0_marshal_byref_struct () {
546                 SimpleStruct s = new SimpleStruct ();
547                 s.a = true;
548                 s.b = false;
549                 s.c = true;
550                 s.d = "ABC";
551                 s.d2 = "DEF";
552
553                 int res = mono_test_marshal_byref_struct (ref s, true, false, true, "ABC");
554                 if (res != 0)
555                         return 1;
556                 if (s.a != false || s.b != true || s.c != false || s.d != "DEF")
557                         return 2;
558                 return 0;
559         }
560
561         public static int test_0_marshal_byref_struct_in () {
562                 SimpleStruct s = new SimpleStruct ();
563                 s.a = true;
564                 s.b = false;
565                 s.c = true;
566                 s.d = "ABC";
567                 s.d2 = "DEF";
568
569                 int res = mono_test_marshal_byref_struct_in (ref s, true, false, true, "ABC");
570                 if (res != 0)
571                         return 1;
572                 if (s.a != true || s.b != false || s.c != true || s.d != "ABC")
573                         return 2;
574                 return 0;
575         }
576
577         public static int test_0_marshal_byref_struct_inout () {
578                 SimpleStruct s = new SimpleStruct ();
579                 s.a = true;
580                 s.b = false;
581                 s.c = true;
582                 s.d = "ABC";
583                 s.d2 = "DEF";
584
585                 int res = mono_test_marshal_byref_struct_inout (ref s, true, false, true, "ABC");
586                 if (res != 0)
587                         return 1;
588                 if (s.a != false || s.b != true || s.c != false || s.d != "DEF")
589                         return 2;
590                 return 0;
591         }
592
593         public static int test_0_marshal_point () {
594                 Point pt = new Point();
595                 pt.x = 1.25;
596                 pt.y = 3.5;
597                 
598                 return mono_test_marshal_point(pt);
599         }
600
601         public static int test_0_marshal_mixed_point () {
602                 MixedPoint mpt = new MixedPoint();
603                 mpt.x = 5;
604                 mpt.y = 6.75;
605                 
606                 return mono_test_marshal_mixed_point(mpt);
607         }
608
609         public static int test_0_marshal_bool_byref () {
610                 bool b = true;
611                 if (mono_test_marshal_bool_byref (99, ref b, 100) != 1)
612                         return 1;
613                 b = false;
614                 if (mono_test_marshal_bool_byref (99, ref b, 100) != 0)
615                         return 12;
616                 if (b != true)
617                         return 13;
618
619                 return 0;
620         }
621
622         public static int test_0_return_vtype () {
623                 SimpleStruct ss = mono_test_return_vtype (new IntPtr (5));
624
625                 if (!ss.a && ss.b && !ss.c && ss.d == "TEST" && ss.d2 == "TEST2")
626                         return 0;
627
628                 return 1;
629         }
630
631         public static int test_0_marshal_stringbuilder () {
632                 StringBuilder sb = new StringBuilder(255);
633                 sb.Append ("ABCD");
634                 mono_test_marshal_stringbuilder (sb, sb.Capacity);
635                 String res = sb.ToString();
636
637                 if (res != "This is my message.  Isn't it nice?")
638                         return 1;  
639
640                 // Test StringBuilder with default capacity (16)
641                 StringBuilder sb2 = new StringBuilder();
642                 mono_test_marshal_stringbuilder_default (sb2, sb2.Capacity);
643                 if (sb2.ToString () != "This is my messa")
644                         return 2;
645
646                 return 0;
647         }
648
649         public static int test_0_marshal_stringbuilder_unicode () {
650                 StringBuilder sb = new StringBuilder(255);
651                 mono_test_marshal_stringbuilder_unicode (sb, sb.Capacity);
652                 String res = sb.ToString();
653
654                 if (res != "This is my message.  Isn't it nice?")
655                         return 1;  
656
657                 // Test StringBuilder with default capacity (16)
658                 StringBuilder sb2 = new StringBuilder();
659                 mono_test_marshal_stringbuilder_unicode (sb2, sb2.Capacity);
660                 if (sb2.ToString () != "This is my messa")
661                         return 2;
662                 
663                 return 0;
664         }
665
666         public static int test_0_marshal_empty_string_array () {
667                 return mono_test_marshal_empty_string_array (null);
668         }
669
670         public static int test_0_marshal_string_array () {
671                 return mono_test_marshal_string_array (new String [] { "ABC", "DEF" });
672         }
673
674         public static int test_0_marshal_unicode_string_array () {
675                 return mono_test_marshal_unicode_string_array (new String [] { "ABC", "DEF" }, new String [] { "ABC", "DEF" });
676         }
677
678         public static int test_0_marshal_stringbuilder_array () {
679                 StringBuilder sb1 = new StringBuilder ("ABC");
680                 StringBuilder sb2 = new StringBuilder ("DEF");
681
682                 int res = mono_test_marshal_stringbuilder_array (new StringBuilder [] { sb1, sb2 });
683                 if (res != 0)
684                         return res;
685                 if (sb1.ToString () != "DEF")
686                         return 5;
687                 if (sb2.ToString () != "ABC")
688                         return 6;
689                 return 0;
690         }
691
692         public static int test_0_last_error () {
693                 mono_test_last_error (5);
694                 if (Marshal.GetLastWin32Error () == 5)
695                         return 0;
696                 else
697                         return 1;
698         }
699
700         public static int test_0_library_not_found () {
701
702                 try {
703                         mono_entry_point_not_found ();
704                         return 1;
705                 }
706                 catch (EntryPointNotFoundException) {
707                 }
708
709                 return 0;
710         }
711
712         public static int test_0_entry_point_not_found () {
713
714                 try {
715                         mono_library_not_found ();
716                         return 1;
717                 }
718                 catch (DllNotFoundException) {
719                 }
720
721                 return 0;
722         }
723
724         /* Check that the runtime trims .dll from the library name */
725         public static int test_0_trim_dll_from_name () {
726
727                 mono_test_marshal_char_2 ('A');
728
729                 return 0;
730         }
731
732         /* Check that the runtime adds lib to to the library name */
733         public static int test_0_add_lib_to_name () {
734
735                 mono_test_marshal_char_3 ('A');
736
737                 return 0;
738         }
739
740         class C {
741                 public int i;
742         }
743
744         public static int test_0_asany () {
745                 if (mono_test_asany (5, 1) != 0)
746                         return 1;
747
748                 if (mono_test_asany ("ABC", 2) != 0)
749                         return 2;
750
751                 SimpleStruct2 ss2 = new  SimpleStruct2 ();
752                 ss2.b = true;
753                 ss2.d = "TEST";
754                 ss2.e = 99;
755                 ss2.f = 1.5;
756                 ss2.g = 42;
757                 ss2.h = 123L;
758
759                 if (mono_test_asany (ss2, 3) != 0)
760                         return 3;
761
762                 if (mono_test_asany_unicode ("ABC", 4) != 0)
763                         return 4;
764
765                 try {
766                         C c = new C ();
767                         c.i = 5;
768                         mono_test_asany (c, 0);
769                         return 5;
770                 }
771                 catch (ArgumentException) {
772                 }
773
774                 try {
775                         mono_test_asany (new Object (), 0);
776                         return 6;
777                 }
778                 catch (ArgumentException) {
779                 }
780
781                 return 0;
782         }
783
784         /* AsAny marshalling + [In, Out] */
785
786         public static int test_0_asany_in () {
787                 // Struct
788                 AsAnyStruct str = new AsAnyStruct(1,2,3, "ABC");
789                 mono_test_asany_in (str);
790
791                 // Formatted Class
792                 AsAnyClass cls = new AsAnyClass(1,2,3, "ABC");
793                 mono_test_asany_in (cls);
794                 if ((cls.i != 1) || (cls.j != 2) || (cls.k != 3))
795                         return 1;
796
797                 // Boxed Struct
798                 object obj = new AsAnyStruct(1,2,3, "ABC");
799                 mono_test_asany_in (obj);
800                 str = (AsAnyStruct)obj;
801                 if ((str.i != 1) || (str.j != 2) || (str.k != 3))
802                         return 2;
803
804                 return 0;
805         }
806
807         public static int test_0_asany_out () {
808                 // Struct
809                 AsAnyStruct str = new AsAnyStruct(1,2,3, "ABC");
810                 mono_test_asany_out (str);
811
812                 // Formatted Class
813                 AsAnyClass cls = new AsAnyClass(1,2,3, "ABC");
814                 mono_test_asany_out (cls);
815                 if ((cls.i != 10) || (cls.j != 20) || (cls.k != 30))
816                         return 1;
817
818                 // Boxed Struct
819                 object obj = new AsAnyStruct(1,2,3, "ABC");
820                 mono_test_asany_out (obj);
821                 str = (AsAnyStruct)obj;
822                 if ((str.i != 10) || (str.j != 20) || (str.k != 30))
823                         return 2;
824
825                 return 0;
826         }
827
828         public static int test_0_asany_inout () {
829                 // Struct
830                 AsAnyStruct str = new AsAnyStruct(1,2,3, "ABC");
831                 mono_test_asany_inout (str);
832
833                 // Formatted Class
834                 AsAnyClass cls = new AsAnyClass(1,2,3, "ABC");
835                 mono_test_asany_inout (cls);
836                 if ((cls.i != 10) || (cls.j != 20) || (cls.k != 30))
837                         return 1;
838
839                 // Boxed Struct
840                 object obj = new AsAnyStruct(1,2,3, "ABC");
841                 mono_test_asany_inout (obj);
842                 str = (AsAnyStruct)obj;
843                 if ((str.i != 10) || (str.j != 20) || (str.k != 30))
844                         return 2;
845
846                 return 0;
847         }
848
849         /* Byref String Array */
850
851         [DllImport ("libtest", EntryPoint="mono_test_marshal_byref_string_array")]
852         public static extern int mono_test_marshal_byref_string_array (ref string[] data);
853
854         public static int test_0_byref_string_array () {
855
856                 string[] arr = null;
857
858                 if (mono_test_marshal_byref_string_array (ref arr) != 0)
859                         return 1;
860
861                 arr = new string[] { "Alpha", "Beta", "Gamma" };
862
863                 if (mono_test_marshal_byref_string_array (ref arr) != 1)
864                         return 2;
865
866                 /* FIXME: Test returned array and out case */
867
868                 return 0;
869         }
870
871         /*
872          * AMD64 small structs-by-value tests.
873          */
874
875         /* TEST 1: 16 byte long INTEGER struct */
876
877         [StructLayout(LayoutKind.Sequential)]
878         public struct Amd64Struct1 {
879                 public int i;
880                 public int j;
881                 public int k;
882                 public int l;
883         }
884         
885         [DllImport ("libtest", EntryPoint="mono_test_marshal_amd64_pass_return_struct1")]
886         public static extern Amd64Struct1 mono_test_marshal_amd64_pass_return_struct1 (Amd64Struct1 s);
887
888         public static int test_0_amd64_struct1 () {
889                 Amd64Struct1 s = new Amd64Struct1 ();
890                 s.i = 5;
891                 s.j = -5;
892                 s.k = 0xffffff;
893                 s.l = 0xfffffff;
894
895                 Amd64Struct1 s2 = mono_test_marshal_amd64_pass_return_struct1 (s);
896
897                 return ((s2.i == 6) && (s2.j == -4) && (s2.k == 0x1000000) && (s2.l == 0x10000000)) ? 0 : 1;
898         }
899
900         /* TEST 2: 8 byte long INTEGER struct */
901
902         [StructLayout(LayoutKind.Sequential)]
903         public struct Amd64Struct2 {
904                 public int i;
905                 public int j;
906         }
907         
908         [DllImport ("libtest", EntryPoint="mono_test_marshal_amd64_pass_return_struct2")]
909         public static extern Amd64Struct2 mono_test_marshal_amd64_pass_return_struct2 (Amd64Struct2 s);
910
911         public static int test_0_amd64_struct2 () {
912                 Amd64Struct2 s = new Amd64Struct2 ();
913                 s.i = 5;
914                 s.j = -5;
915
916                 Amd64Struct2 s2 = mono_test_marshal_amd64_pass_return_struct2 (s);
917
918                 return ((s2.i == 6) && (s2.j == -4)) ? 0 : 1;
919         }
920
921         /* TEST 3: 4 byte long INTEGER struct */
922
923         [StructLayout(LayoutKind.Sequential)]
924         public struct Amd64Struct3 {
925                 public int i;
926         }
927         
928         [DllImport ("libtest", EntryPoint="mono_test_marshal_amd64_pass_return_struct3")]
929         public static extern Amd64Struct3 mono_test_marshal_amd64_pass_return_struct3 (Amd64Struct3 s);
930
931         public static int test_0_amd64_struct3 () {
932                 Amd64Struct3 s = new Amd64Struct3 ();
933                 s.i = -5;
934
935                 Amd64Struct3 s2 = mono_test_marshal_amd64_pass_return_struct3 (s);
936
937                 return (s2.i == -4) ? 0 : 1;
938         }
939
940         /* Test 4: 16 byte long FLOAT struct */
941
942         [StructLayout(LayoutKind.Sequential)]
943         public struct Amd64Struct4 {
944                 public double d1, d2;
945         }
946         
947         [DllImport ("libtest", EntryPoint="mono_test_marshal_amd64_pass_return_struct4")]
948         public static extern Amd64Struct4 mono_test_marshal_amd64_pass_return_struct4 (Amd64Struct4 s);
949
950         public static int test_0_amd64_struct4 () {
951                 Amd64Struct4 s = new Amd64Struct4 ();
952                 s.d1 = 5.0;
953                 s.d2 = -5.0;
954
955                 Amd64Struct4 s2 = mono_test_marshal_amd64_pass_return_struct4 (s);
956
957                 return (s2.d1 == 6.0 && s2.d2 == -4.0) ? 0 : 1;
958         }
959
960         /*
961          * IA64 struct tests
962          */
963
964         /* Test 5: Float HFA */
965
966         [StructLayout(LayoutKind.Sequential)]
967         public struct TestStruct5 {
968                 public float d1, d2;
969         }
970         
971         [DllImport ("libtest", EntryPoint="mono_test_marshal_ia64_pass_return_struct5")]
972         public static extern TestStruct5 mono_test_marshal_ia64_pass_return_struct5 (double d1, double d2, TestStruct5 s, double f3, double f4);
973
974         public static int test_0_ia64_struct5 () {
975                 TestStruct5 s = new TestStruct5 ();
976                 s.d1 = 5.0f;
977                 s.d2 = -5.0f;
978
979                 TestStruct5 s2 = mono_test_marshal_ia64_pass_return_struct5 (1.0, 2.0, s, 3.0, 4.0);
980
981                 return (s2.d1 == 8.0 && s2.d2 == 2.0) ? 0 : 1;
982         }
983
984         /* Test 6: Double HFA */
985
986         [StructLayout(LayoutKind.Sequential)]
987         public struct TestStruct6 {
988                 public double d1, d2;
989         }
990         
991         [DllImport ("libtest", EntryPoint="mono_test_marshal_ia64_pass_return_struct6")]
992         public static extern TestStruct6 mono_test_marshal_ia64_pass_return_struct6 (double d1, double d2, TestStruct6 s, double f3, double f4);
993
994         public static int test_0_ia64_struct6 () {
995                 TestStruct6 s = new TestStruct6 ();
996                 s.d1 = 6.0;
997                 s.d2 = -6.0;
998
999                 TestStruct6 s2 = mono_test_marshal_ia64_pass_return_struct6 (1.0, 2.0, s, 3.0, 4.0);
1000
1001                 return (s2.d1 == 9.0 && s2.d2 == 1.0) ? 0 : 1;
1002         }
1003         
1004         /* Blittable class */
1005         [DllImport("libtest")]
1006         private static extern BlittableClass TestBlittableClass (BlittableClass vl);
1007
1008         public static int test_0_marshal_blittable_class () {
1009                 BlittableClass v1 = new BlittableClass ();
1010
1011                 /* Since it is blittable, it looks like it is passed as in/out */
1012                 BlittableClass v2 = TestBlittableClass (v1);
1013
1014                 if (v1.a != 2 || v1.b != 3)
1015                         return 1;
1016                 
1017                 if (v2.a != 2 || v2.b != 3)
1018                         return 2;
1019
1020                 // Test null
1021                 BlittableClass v3 = TestBlittableClass (null);
1022
1023                 if (v3.a != 42 || v3.b != 43)
1024                         return 3;
1025                 
1026                 return 0;
1027         }
1028
1029         public static int test_0_marshal_byval_class () {
1030                 SimpleObj obj0 = new SimpleObj ();
1031                 obj0.str = "T1";
1032                 obj0.i = 4;
1033                 
1034                 if (class_marshal_test0 (obj0) != 0)
1035                         return 1;
1036
1037                 return 0;
1038         }
1039
1040         public static int test_0_marshal_byval_class_null () {
1041                 if (class_marshal_test4 (null) != 0)
1042                         return 1;
1043
1044                 return 0;
1045         }
1046
1047         public static int test_0_marshal_out_class () {
1048                 SimpleObj obj1;
1049
1050                 class_marshal_test1 (out obj1);
1051
1052                 if (obj1.str != "ABC")
1053                         return 1;
1054
1055                 if (obj1.i != 5)
1056                         return 2;
1057
1058                 return 0;
1059         }
1060
1061         public static int test_0_marshal_string () {
1062                 return string_marshal_test0 ("TEST0");
1063         }
1064
1065         public static int test_0_marshal_out_string () {
1066                 string res;
1067                 
1068                 string_marshal_test1 (out res);
1069
1070                 if (res != "TEST1")
1071                         return 1;
1072
1073                 return 0;
1074         }
1075
1076         public static int test_0_marshal_byref_string () {
1077                 string res = "TEST1";
1078
1079                 return string_marshal_test2 (ref res);
1080         }
1081
1082         public static int test_0_marshal_null_string () {
1083                 return string_marshal_test3 (null);
1084         }
1085
1086         [DllImport ("libtest", EntryPoint="mono_test_stdcall_name_mangling", CallingConvention=CallingConvention.StdCall)]
1087         public static extern int mono_test_stdcall_name_mangling (int a, int b, int c);
1088
1089         public static int test_0_stdcall_name_mangling () {
1090                 return mono_test_stdcall_name_mangling (0, 1, 2) == 3 ? 0 : 1;
1091         }
1092
1093         /*
1094          * Pointers to structures can not be passed
1095          */
1096
1097         public struct CharInfo {
1098                 public char Character;
1099                 public short Attributes;
1100         }
1101
1102         [DllImport ("libtest", EntryPoint="mono_test_marshal_struct")]
1103         public static unsafe extern int mono_test_marshal_ptr_to_struct (CharInfo *ptr);
1104
1105         public static unsafe int test_0_marshal_ptr_to_struct () {
1106                 CharInfo [] buffer = new CharInfo [1];
1107                 fixed (CharInfo *ptr = &buffer [0]) {
1108                         try {
1109                                 mono_test_marshal_ptr_to_struct (ptr);
1110                                 return 1;
1111                         }
1112                         catch (MarshalDirectiveException) {
1113                                 return 0;
1114                         }
1115                 }
1116                 return 1;
1117         }
1118
1119         /*
1120          * LPWStr marshalling
1121          */
1122
1123         [DllImport("libtest", EntryPoint="test_lpwstr_marshal")]
1124         [return: MarshalAs(UnmanagedType.LPWStr)]
1125         private static extern string mono_test_marshal_lpwstr_marshal(
1126                 [MarshalAs(UnmanagedType.LPWStr)] string s,
1127                 int length );
1128
1129         [DllImport("libtest", EntryPoint="test_lpwstr_marshal", CharSet=CharSet.Unicode)]
1130         private static extern string mono_test_marshal_lpwstr_marshal2(
1131                 string s,
1132                 int length );
1133
1134         public static int test_0_pass_return_lwpstr () {
1135                 string s = "ABC";
1136                 
1137                 string res = mono_test_marshal_lpwstr_marshal (s, s.Length);
1138
1139                 if (res != "ABC")
1140                         return 1;
1141
1142                 string res2 = mono_test_marshal_lpwstr_marshal2 (s, s.Length);
1143
1144                 if (res2 != "ABC")
1145                         return 2;
1146                 
1147                 return 0;               
1148         }
1149
1150         /*
1151          * Byref bool marshalling
1152          */
1153
1154         [DllImport("libtest")]
1155         extern static int marshal_test_ref_bool
1156         (
1157                 int i, 
1158                 [MarshalAs(UnmanagedType.I1)] ref bool b1, 
1159                 [MarshalAs(UnmanagedType.VariantBool)] ref bool b2, 
1160                 ref bool b3
1161         );
1162
1163         public static int test_0_pass_byref_bool () {
1164                 for (int i = 0; i < 8; i++)
1165                 {
1166                         bool b1 = (i & 4) != 0;
1167                         bool b2 = (i & 2) != 0;
1168                         bool b3 = (i & 1) != 0;
1169                         bool orig_b1 = b1, orig_b2 = b2, orig_b3 = b3;
1170                         if (marshal_test_ref_bool(i, ref b1, ref b2, ref b3) != 0)
1171                                 return 4 * i + 1;
1172                         if (b1 != !orig_b1)
1173                                 return 4 * i + 2;
1174                         if (b2 != !orig_b2)
1175                                 return 4 * i + 3;
1176                         if (b3 != !orig_b3)
1177                                 return 4 * i + 4;
1178                 }
1179
1180                 return 0;
1181         }
1182
1183         /*
1184          * Bool struct field marshalling
1185          */
1186
1187         struct BoolStruct
1188         {
1189                 public int i;
1190                 [MarshalAs(UnmanagedType.I1)] public bool b1;
1191                 [MarshalAs(UnmanagedType.VariantBool)] public bool b2;
1192                 public bool b3;
1193         }
1194
1195         [DllImport("libtest")]
1196         extern static int marshal_test_bool_struct(ref BoolStruct s);
1197
1198         public static int test_0_pass_bool_in_struct () {
1199                 for (int i = 0; i < 8; i++)
1200                 {
1201                         BoolStruct s = new BoolStruct();
1202                         s.i = i;
1203                         s.b1 = (i & 4) != 0;
1204                         s.b2 = (i & 2) != 0;
1205                         s.b3 = (i & 1) != 0;
1206                         BoolStruct orig = s;
1207                         if (marshal_test_bool_struct(ref s) != 0)
1208                                 return 4 * i + 33;
1209                         if (s.b1 != !orig.b1)
1210                                 return 4 * i + 34;
1211                         if (s.b2 != !orig.b2)
1212                                 return 4 * i + 35;
1213                         if (s.b3 != !orig.b3)
1214                                 return 4 * i + 36;
1215                 }
1216
1217                 return 0;
1218         }
1219
1220         /*
1221          * Invoking pinvoke methods through delegates
1222          */
1223
1224         delegate int MyDelegate (string name);
1225
1226         [DllImport ("libtest", EntryPoint="mono_test_puts_static")]
1227         public static extern int puts_static (string name);
1228
1229         public static int test_0_invoke_pinvoke_through_delegate () {
1230                 puts_static ("A simple Test for PInvoke 1");
1231
1232                 MyDelegate d = new MyDelegate (puts_static);
1233                 d ("A simple Test for PInvoke 2");
1234
1235                 object [] args = {"A simple Test for PInvoke 3"};
1236                 d.DynamicInvoke (args);
1237
1238                 return 0;
1239         }
1240
1241         /*
1242          * Missing virtual pinvoke methods
1243          */
1244
1245         public class T {
1246
1247                 public virtual object MyClone ()
1248                 {
1249                         return null;
1250                 }
1251         }
1252
1253         public class T2 : T {
1254                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1255                 public override extern object MyClone ();
1256         }
1257
1258         public static int test_0_missing_virtual_pinvoke_method () {
1259                 T2 t = new T2 ();
1260
1261                 try {
1262                         t.MyClone ();
1263                 } catch (Exception ex) {
1264                         return 0;
1265                 }
1266                 
1267                 return 1;
1268         }
1269 }
1270