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