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