Merge pull request #1200 from akoeplinger/remove-jvm
[mono.git] / mono / tests / pinvoke3.cs
1 //
2 // pinvoke3.cs:
3 //
4 //  Tests for native->managed marshalling
5 //
6
7 using System;
8 using System.Text;
9 using System.Runtime.InteropServices;
10 using System.Threading;
11
12 public class Tests {
13
14         [StructLayout (LayoutKind.Sequential)]
15         public struct SimpleStruct {
16                 public bool a;
17                 public bool b;
18                 public bool c;
19                 public string d;
20                 [MarshalAs(UnmanagedType.LPWStr)]
21                 public string d2;
22         }
23
24         [StructLayout (LayoutKind.Sequential)]
25         public class SimpleClass {
26                 public bool a;
27                 public bool b;
28                 public bool c;
29                 public string d;
30         }
31
32         public static SimpleStruct delegate_test_struct (SimpleStruct ss)
33         {
34                 SimpleStruct res;
35
36                 res.a = !ss.a;
37                 res.b = !ss.b;
38                 res.c = !ss.c;
39                 res.d = ss.d + "-RES";
40                 res.d2 = ss.d2 + "-RES";
41
42                 return res;
43         }
44
45         public static int delegate_test_struct_byref (int a, ref SimpleStruct ss, int b)
46         {
47                 if (a == 1 && b == 2 && ss.a && !ss.b && ss.c && ss.d == "TEST2") {
48                         ss.a = true;
49                         ss.b = true;
50                         ss.c = true;
51                         ss.d = "TEST3";
52                         return 0;
53                 }
54
55                 return 1;
56         }
57
58         public static int delegate_test_struct_out (int a, out SimpleStruct ss, int b)
59         {
60                 ss.a = true;
61                 ss.b = true;
62                 ss.c = true;
63                 ss.d = "TEST3";
64                 ss.d2 = "TEST4";
65
66                 return 0;
67         }
68
69         public static int delegate_test_struct_in (int a, [In] ref SimpleStruct ss, int b)
70         {
71                 if (a == 1 && b == 2 && ss.a && !ss.b && ss.c && ss.d == "TEST2") {
72                         ss.a = true;
73                         ss.b = true;
74                         ss.c = true;
75                         ss.d = "TEST3";
76                         return 0;
77                 }
78
79                 return 1;
80         }
81
82         public static SimpleClass delegate_test_class (SimpleClass ss)
83         {
84                 if (ss == null)
85                         return null;
86
87                 if (! (!ss.a && ss.b && !ss.c && ss.d == "TEST"))
88                         return null;
89
90                 SimpleClass res = ss;
91
92                 return res;
93         }
94
95         public static int delegate_test_class_byref (ref SimpleClass ss)
96         {
97                 if (ss == null)
98                         return -1;
99
100                 if (!ss.a && ss.b && !ss.c && ss.d == "TEST") {
101                         ss.a = true;
102                         ss.b = false;
103                         ss.c = true;
104                         ss.d = "RES";
105
106                         return 0;
107                 }
108
109                 return 1;
110         }
111
112         public static int delegate_test_class_out (out SimpleClass ss)
113         {
114                 ss = new SimpleClass ();
115                 ss.a = true;
116                 ss.b = false;
117                 ss.c = true;
118                 ss.d = "RES";
119
120                 return 0;
121         }
122
123         public static int delegate_test_primitive_byref (ref int i)
124         {
125                 if (i != 1)
126                         return 1;
127                 
128                 i = 2;
129                 return 0;
130         }
131
132         public static int delegate_test_string_marshalling (string s)
133         {
134                 return s == "ABC" ? 0 : 1;
135         }
136
137         public static int delegate_test_string_builder_marshalling (StringBuilder s)
138         {
139                 if (s == null)
140                         return 2;
141                 else
142                         return s.ToString () == "ABC" ? 0 : 1;
143         }
144
145         [DllImport ("libtest", EntryPoint="mono_test_ref_vtype")]
146         public static extern int mono_test_ref_vtype (int a, ref SimpleStruct ss, int b, TestDelegate d);
147
148         public delegate int OutStructDelegate (int a, out SimpleStruct ss, int b);
149
150         public delegate int InStructDelegate (int a, [In] ref SimpleStruct ss, int b);
151
152         [DllImport ("libtest", EntryPoint="mono_test_marshal_out_struct")]
153         public static extern int mono_test_marshal_out_struct (int a, out SimpleStruct ss, int b, OutStructDelegate d);
154
155         [DllImport ("libtest", EntryPoint="mono_test_marshal_in_struct")]
156         public static extern int mono_test_marshal_in_struct (int a, ref SimpleStruct ss, int b, InStructDelegate d);
157         
158         [DllImport ("libtest", EntryPoint="mono_test_marshal_delegate2")]
159         public static extern int mono_test_marshal_delegate2 (SimpleDelegate2 d);
160
161         [DllImport ("libtest", EntryPoint="mono_test_marshal_delegate4")]
162         public static extern int mono_test_marshal_delegate4 (SimpleDelegate4 d);
163
164         [DllImport ("libtest", EntryPoint="mono_test_marshal_delegate5")]
165         public static extern int mono_test_marshal_delegate5 (SimpleDelegate5 d);
166
167         [DllImport ("libtest", EntryPoint="mono_test_marshal_delegate6")]
168         public static extern int mono_test_marshal_delegate6 (SimpleDelegate5 d);
169
170         [DllImport ("libtest", EntryPoint="mono_test_marshal_delegate7")]
171         public static extern int mono_test_marshal_delegate7 (SimpleDelegate7 d);
172
173         [DllImport ("libtest", EntryPoint="mono_test_marshal_delegate8", CharSet=CharSet.Unicode)]
174         public static extern int mono_test_marshal_delegate8 (SimpleDelegate8 d, string s);
175
176         [DllImport ("libtest", EntryPoint="mono_test_marshal_delegate9")]
177         public static extern int mono_test_marshal_delegate9 (SimpleDelegate9 d, return_int_delegate d2);
178
179         [DllImport ("libtest", EntryPoint="mono_test_marshal_delegate10")]
180         public static extern int mono_test_marshal_delegate10 (SimpleDelegate9 d);
181
182         [DllImport ("libtest", EntryPoint="mono_test_marshal_delegate8")]
183         public static extern int mono_test_marshal_delegate11 (SimpleDelegate11 d, string s);
184
185         [DllImport ("libtest", EntryPoint="mono_test_marshal_primitive_byref_delegate")]
186         public static extern int mono_test_marshal_primitive_byref_delegate (PrimitiveByrefDelegate d);
187
188         [DllImport ("libtest", EntryPoint="mono_test_marshal_return_delegate_delegate")]
189         public static extern int mono_test_marshal_return_delegate_delegate (ReturnDelegateDelegate d);
190
191         public delegate int TestDelegate (int a, ref SimpleStruct ss, int b);
192
193         public delegate SimpleStruct SimpleDelegate2 (SimpleStruct ss);
194
195         public delegate SimpleClass SimpleDelegate4 (SimpleClass ss);
196
197         public delegate int SimpleDelegate5 (ref SimpleClass ss);
198
199         public delegate int SimpleDelegate7 (out SimpleClass ss);
200
201         public delegate int SimpleDelegate8 ([MarshalAs (UnmanagedType.LPWStr)] string s1);
202
203         public delegate int return_int_delegate (int i);
204
205         public delegate int SimpleDelegate9 (return_int_delegate del);
206
207         public delegate int SimpleDelegate11 (StringBuilder s1);
208
209         public delegate int PrimitiveByrefDelegate (ref int i);
210
211         public delegate return_int_delegate ReturnDelegateDelegate ();
212
213         public static int Main () {
214                 return TestDriver.RunTests (typeof (Tests));
215         }
216
217         /* Test structures as arguments and return values of delegates */
218         public static int test_0_marshal_struct_delegate () {
219                 SimpleDelegate2 d = new SimpleDelegate2 (delegate_test_struct);
220
221                 return mono_test_marshal_delegate2 (d);
222         }
223
224         /* Test structures as byref arguments of delegates */
225         public static int test_0_marshal_byref_struct_delegate () {
226                 SimpleStruct ss = new SimpleStruct ();
227                 TestDelegate d = new TestDelegate (delegate_test_struct_byref);
228                 
229                 ss.b = true;
230                 ss.d = "TEST1";
231
232                 if (mono_test_ref_vtype (1, ref ss, 2, d) != 0)
233                         return 1;
234
235                 if (! (ss.a && ss.b && ss.c && ss.d == "TEST3"))
236                         return 2;
237                 
238                 return 0;
239         }
240
241         /* Test structures as out arguments of delegates */
242         public static int test_0_marshal_out_struct_delegate () {
243                 SimpleStruct ss = new SimpleStruct ();
244                 OutStructDelegate d = new OutStructDelegate (delegate_test_struct_out);
245
246                 return mono_test_marshal_out_struct (1, out ss, 2, d);
247         }
248
249         /* Test structures as in arguments of delegates */
250         public static int test_0_marshal_in_struct_delegate () {
251                 SimpleStruct ss = new SimpleStruct () { a = true, b = false, c = true, d = "TEST2" };
252                 InStructDelegate d = new InStructDelegate (delegate_test_struct_in);
253
254                 return mono_test_marshal_in_struct (1, ref ss, 2, d);
255         }
256
257         /* Test classes as arguments and return values of delegates */
258         public static int test_0_marshal_class_delegate () {
259                 SimpleDelegate4 d = new SimpleDelegate4 (delegate_test_class);
260
261                 return mono_test_marshal_delegate4 (d);
262         }
263
264         /* Test classes as byref arguments of delegates */
265         public static int test_0_marshal_byref_class_delegate () {
266                 SimpleDelegate5 d = new SimpleDelegate5 (delegate_test_class_byref);
267
268                 return mono_test_marshal_delegate5 (d);
269         }
270
271         /* Test classes as out arguments of delegates */
272         public static int test_0_marshal_out_class_delegate () {
273                 SimpleDelegate7 d = new SimpleDelegate7 (delegate_test_class_out);
274
275                 return mono_test_marshal_delegate7 (d);
276         }
277
278         /* Test string marshalling with delegates */
279         public static int test_0_marshal_string_delegate () {
280                 SimpleDelegate8 d = new SimpleDelegate8 (delegate_test_string_marshalling);
281
282                 return mono_test_marshal_delegate8 (d, "ABC");
283         }
284
285         /* Test string builder marshalling with delegates */
286         public static int test_0_marshal_string_builder_delegate () {
287                 SimpleDelegate11 d = new SimpleDelegate11 (delegate_test_string_builder_marshalling);
288
289                 if (mono_test_marshal_delegate11 (d, null) != 2)
290                         return 2;
291
292                 return mono_test_marshal_delegate11 (d, "ABC");
293         }
294
295         /* Test that the delegate wrapper correctly catches null byref arguments */
296         public static int test_0_marshal_byref_class_delegate_null () {
297                 SimpleDelegate5 d = new SimpleDelegate5 (delegate_test_class_byref);
298                 
299                 try {
300                         mono_test_marshal_delegate6 (d);
301                         return 1;
302                 }
303                 catch (ArgumentNullException ex) {
304                         return 0;
305                 }
306         }
307
308         static int return_self (int i) {
309                 return i;
310         }
311
312         static int call_int_delegate (return_int_delegate d) {
313                 return d (55);
314         }
315
316         public static int test_55_marshal_delegate_delegate () {
317                 SimpleDelegate9 d = new SimpleDelegate9 (call_int_delegate);
318
319                 return mono_test_marshal_delegate9 (d, new return_int_delegate (return_self));
320         }
321
322         public static int test_0_marshal_primitive_byref_delegate () {
323                 PrimitiveByrefDelegate d = new PrimitiveByrefDelegate (delegate_test_primitive_byref);
324
325                 return mono_test_marshal_primitive_byref_delegate (d);
326         }
327
328         public static return_int_delegate return_delegate () {
329                 return new return_int_delegate (return_self);
330         }
331
332         public static int test_55_marshal_return_delegate_delegate () {
333                 return mono_test_marshal_return_delegate_delegate (new ReturnDelegateDelegate (return_delegate));
334         }
335
336         /* Passing and returning strings */
337
338         public delegate String ReturnStringDelegate (String s);
339
340         [DllImport ("libtest", EntryPoint="mono_test_return_string")]
341         public static extern String mono_test_marshal_return_string_delegate (ReturnStringDelegate d);
342
343         public static String managed_return_string (String s) {
344                 if (s != "TEST")
345                         return "";
346                 else
347                         return "12345";
348         }
349
350         public static int test_0_marshal_return_string_delegate () {
351                 ReturnStringDelegate d = new ReturnStringDelegate (managed_return_string);
352                 String s = mono_test_marshal_return_string_delegate (d);
353
354                 return (s == "12345") ? 0 : 1;
355         }
356
357         /* Passing and returning enums */
358
359         public enum FooEnum {
360                 Foo1,
361                 Foo2,
362                 Foo3
363         };
364
365         public delegate FooEnum ReturnEnumDelegate (FooEnum e);
366
367         [DllImport ("libtest", EntryPoint="mono_test_marshal_return_enum_delegate")]
368         public static extern int mono_test_marshal_return_enum_delegate (ReturnEnumDelegate d);
369
370         public static FooEnum managed_return_enum (FooEnum e) {
371                 return (FooEnum)((int)e + 1);
372         }
373
374         public static int test_0_marshal_return_enum_delegate () {
375                 ReturnEnumDelegate d = new ReturnEnumDelegate (managed_return_enum);
376                 FooEnum e = (FooEnum)mono_test_marshal_return_enum_delegate (d);
377
378                 return e == FooEnum.Foo3 ? 0 : 1;
379         }
380
381         /* Passing and returning blittable structs */
382
383         [StructLayout (LayoutKind.Sequential)]
384         public struct BlittableStruct {
385                 public int a, b, c;
386                 public long d;
387         }
388
389         public static BlittableStruct delegate_test_blittable_struct (BlittableStruct ss)
390         {
391                 BlittableStruct res;
392
393                 res.a = -ss.a;
394                 res.b = -ss.b;
395                 res.c = -ss.c;
396                 res.d = -ss.d;
397
398                 return res;
399         }
400
401         public delegate BlittableStruct SimpleDelegate10 (BlittableStruct ss);
402
403         [DllImport ("libtest", EntryPoint="mono_test_marshal_blittable_struct_delegate")]
404         public static extern int mono_test_marshal_blittable_struct_delegate (SimpleDelegate10 d);
405
406         public static int test_0_marshal_blittable_struct_delegate () {
407                 return mono_test_marshal_blittable_struct_delegate (new SimpleDelegate10 (delegate_test_blittable_struct));
408         }
409
410         /*
411          * Passing and returning small structs
412          */
413
414         /* TEST 1: 4 byte long INTEGER struct */
415
416         [StructLayout (LayoutKind.Sequential)]
417         public struct SmallStruct1 {
418                 public int i;
419         }
420
421         public static SmallStruct1 delegate_test_struct (SmallStruct1 ss) {
422                 SmallStruct1 res;
423
424                 res.i = -ss.i;
425                 
426                 return res;
427         }
428
429         public delegate SmallStruct1 SmallStructDelegate1 (SmallStruct1 ss);
430
431         [DllImport ("libtest", EntryPoint="mono_test_marshal_small_struct_delegate1")]
432         public static extern int mono_test_marshal_small_struct_delegate (SmallStructDelegate1 d);
433
434         public static int test_0_marshal_small_struct_delegate1 () {
435                 return mono_test_marshal_small_struct_delegate (new SmallStructDelegate1 (delegate_test_struct));
436         }
437
438         /* TEST 2: 2+2 byte long INTEGER struct */
439
440         [StructLayout (LayoutKind.Sequential)]
441         public struct SmallStruct2 {
442                 public short i, j;
443         }
444
445         public static SmallStruct2 delegate_test_struct (SmallStruct2 ss) {
446                 SmallStruct2 res;
447
448                 res.i = (short)-ss.i;
449                 res.j = (short)-ss.j;
450                 
451                 return res;
452         }
453
454         public delegate SmallStruct2 SmallStructDelegate2 (SmallStruct2 ss);
455
456         [DllImport ("libtest", EntryPoint="mono_test_marshal_small_struct_delegate2")]
457         public static extern int mono_test_marshal_small_struct_delegate (SmallStructDelegate2 d);
458
459         public static int test_0_marshal_small_struct_delegate2 () {
460                 return mono_test_marshal_small_struct_delegate (new SmallStructDelegate2 (delegate_test_struct));
461         }
462
463         /* TEST 3: 2+1 byte long INTEGER struct */
464
465         [StructLayout (LayoutKind.Sequential)]
466         public struct SmallStruct3 {
467                 public short i;
468                 public byte j;
469         }
470
471         public static SmallStruct3 delegate_test_struct (SmallStruct3 ss) {
472                 SmallStruct3 res;
473
474                 res.i = (short)-ss.i;
475                 res.j = (byte)-ss.j;
476                 
477                 return res;
478         }
479
480         public delegate SmallStruct3 SmallStructDelegate3 (SmallStruct3 ss);
481
482         [DllImport ("libtest", EntryPoint="mono_test_marshal_small_struct_delegate3")]
483         public static extern int mono_test_marshal_small_struct_delegate (SmallStructDelegate3 d);
484
485         public static int test_0_marshal_small_struct_delegate3 () {
486                 return mono_test_marshal_small_struct_delegate (new SmallStructDelegate3 (delegate_test_struct));
487         }
488
489         /* TEST 4: 2 byte long INTEGER struct */
490
491         [StructLayout (LayoutKind.Sequential)]
492         public struct SmallStruct4 {
493                 public short i;
494         }
495
496         public static SmallStruct4 delegate_test_struct (SmallStruct4 ss) {
497                 SmallStruct4 res;
498
499                 res.i = (short)-ss.i;
500                 
501                 return res;
502         }
503
504         public delegate SmallStruct4 SmallStructDelegate4 (SmallStruct4 ss);
505
506         [DllImport ("libtest", EntryPoint="mono_test_marshal_small_struct_delegate4")]
507         public static extern int mono_test_marshal_small_struct_delegate (SmallStructDelegate4 d);
508
509         public static int test_0_marshal_small_struct_delegate4 () {
510                 return mono_test_marshal_small_struct_delegate (new SmallStructDelegate4 (delegate_test_struct));
511         }
512
513         /* TEST 5: 8 byte long INTEGER struct */
514
515         [StructLayout (LayoutKind.Sequential)]
516         public struct SmallStruct5 {
517                 public long l;
518         }
519
520         public static SmallStruct5 delegate_test_struct (SmallStruct5 ss) {
521                 SmallStruct5 res;
522
523                 res.l = -ss.l;
524                 
525                 return res;
526         }
527
528         public delegate SmallStruct5 SmallStructDelegate5 (SmallStruct5 ss);
529
530         [DllImport ("libtest", EntryPoint="mono_test_marshal_small_struct_delegate5")]
531         public static extern int mono_test_marshal_small_struct_delegate (SmallStructDelegate5 d);
532
533         public static int test_0_marshal_small_struct_delegate5 () {
534                 return mono_test_marshal_small_struct_delegate (new SmallStructDelegate5 (delegate_test_struct));
535         }
536
537         /* TEST 6: 4+4 byte long INTEGER struct */
538
539         [StructLayout (LayoutKind.Sequential)]
540         public struct SmallStruct6 {
541                 public int i, j;
542         }
543
544         public static SmallStruct6 delegate_test_struct (SmallStruct6 ss) {
545                 SmallStruct6 res;
546
547                 res.i = -ss.i;
548                 res.j = -ss.j;
549                 
550                 return res;
551         }
552
553         public delegate SmallStruct6 SmallStructDelegate6 (SmallStruct6 ss);
554
555         [DllImport ("libtest", EntryPoint="mono_test_marshal_small_struct_delegate6")]
556         public static extern int mono_test_marshal_small_struct_delegate (SmallStructDelegate6 d);
557
558         public static int test_0_marshal_small_struct_delegate6 () {
559                 return mono_test_marshal_small_struct_delegate (new SmallStructDelegate6 (delegate_test_struct));
560         }
561
562         /* TEST 7: 4+2 byte long INTEGER struct */
563
564         [StructLayout (LayoutKind.Sequential)]
565         public struct SmallStruct7 {
566                 public int i;
567                 public short j;
568         }
569
570         public static SmallStruct7 delegate_test_struct (SmallStruct7 ss) {
571                 SmallStruct7 res;
572
573                 res.i = -ss.i;
574                 res.j = (short)-ss.j;
575                 
576                 return res;
577         }
578
579         public delegate SmallStruct7 SmallStructDelegate7 (SmallStruct7 ss);
580
581         [DllImport ("libtest", EntryPoint="mono_test_marshal_small_struct_delegate7")]
582         public static extern int mono_test_marshal_small_struct_delegate (SmallStructDelegate7 d);
583
584         public static int test_0_marshal_small_struct_delegate7 () {
585                 return mono_test_marshal_small_struct_delegate (new SmallStructDelegate7 (delegate_test_struct));
586         }
587
588         /* TEST 8: 4 byte long FLOAT struct */
589
590         [StructLayout (LayoutKind.Sequential)]
591         public struct SmallStruct8 {
592                 public float i;
593         }
594
595         public static SmallStruct8 delegate_test_struct (SmallStruct8 ss) {
596                 SmallStruct8 res;
597
598                 res.i = -ss.i;
599                 
600                 return res;
601         }
602
603         public delegate SmallStruct8 SmallStructDelegate8 (SmallStruct8 ss);
604
605         [DllImport ("libtest", EntryPoint="mono_test_marshal_small_struct_delegate8")]
606         public static extern int mono_test_marshal_small_struct_delegate (SmallStructDelegate8 d);
607
608         public static int test_0_marshal_small_struct_delegate8 () {
609                 return mono_test_marshal_small_struct_delegate (new SmallStructDelegate8 (delegate_test_struct));
610         }
611
612         /* TEST 9: 8 byte long FLOAT struct */
613
614         [StructLayout (LayoutKind.Sequential)]
615         public struct SmallStruct9 {
616                 public double i;
617         }
618
619         public static SmallStruct9 delegate_test_struct (SmallStruct9 ss) {
620                 SmallStruct9 res;
621
622                 res.i = -ss.i;
623                 
624                 return res;
625         }
626
627         public delegate SmallStruct9 SmallStructDelegate9 (SmallStruct9 ss);
628
629         [DllImport ("libtest", EntryPoint="mono_test_marshal_small_struct_delegate9")]
630         public static extern int mono_test_marshal_small_struct_delegate (SmallStructDelegate9 d);
631
632         public static int test_0_marshal_small_struct_delegate9 () {
633                 return mono_test_marshal_small_struct_delegate (new SmallStructDelegate9 (delegate_test_struct));
634         }
635
636         /* TEST 10: 4+4 byte long FLOAT struct */
637
638         [StructLayout (LayoutKind.Sequential)]
639         public struct SmallStruct10 {
640                 public float i;
641                 public float j;
642         }
643
644         public static SmallStruct10 delegate_test_struct (SmallStruct10 ss) {
645                 SmallStruct10 res;
646
647                 res.i = -ss.i;
648                 res.j = -ss.j;
649                 
650                 return res;
651         }
652
653         public delegate SmallStruct10 SmallStructDelegate10 (SmallStruct10 ss);
654
655         [DllImport ("libtest", EntryPoint="mono_test_marshal_small_struct_delegate10")]
656         public static extern int mono_test_marshal_small_struct_delegate (SmallStructDelegate10 d);
657
658         public static int test_0_marshal_small_struct_delegate10 () {
659                 return mono_test_marshal_small_struct_delegate (new SmallStructDelegate10 (delegate_test_struct));
660         }
661
662         /* TEST 11: 4+4 byte long MIXED struct */
663
664         [StructLayout (LayoutKind.Sequential)]
665         public struct SmallStruct11 {
666                 public float i;
667                 public int j;
668         }
669
670         public static SmallStruct11 delegate_test_struct (SmallStruct11 ss) {
671                 SmallStruct11 res;
672
673                 res.i = -ss.i;
674                 res.j = -ss.j;
675                 
676                 return res;
677         }
678
679         public delegate SmallStruct11 SmallStructDelegate11 (SmallStruct11 ss);
680
681         [DllImport ("libtest", EntryPoint="mono_test_marshal_small_struct_delegate11")]
682         public static extern int mono_test_marshal_small_struct_delegate (SmallStructDelegate11 d);
683
684         public static int test_0_marshal_small_struct_delegate11 () {
685                 return mono_test_marshal_small_struct_delegate (new SmallStructDelegate11 (delegate_test_struct));
686         }
687
688         /*
689          * Passing arrays
690          */
691         public delegate int ArrayDelegate1 (int i, 
692                                                                                 string j, 
693                                                                                 [In, MarshalAs(UnmanagedType.LPArray, 
694                                                                                                            ArraySubType=UnmanagedType.LPStr, SizeParamIndex=0)] string[] arr);
695
696         [DllImport ("libtest", EntryPoint="mono_test_marshal_array_delegate")]
697         public static extern int mono_test_marshal_array_delegate1 (string[] arr, int len, ArrayDelegate1 d);
698
699         public static int array_delegate1 (int i, string j, string[] arr) {
700                 if (arr.Length != 2)
701                         return 1;
702                 if ((arr [0] != "ABC") || (arr [1] != "DEF"))
703                         return 2;
704                 return 0;
705         }
706
707         public static int test_0_marshal_array_delegate_string () {     
708                 string[] arr = new string [] { "ABC", "DEF" };
709                 return mono_test_marshal_array_delegate1 (arr, arr.Length, new ArrayDelegate1 (array_delegate1));
710         }
711
712         public static int array_delegate2 (int i, string j, string[] arr) {
713                 return (arr == null) ? 0 : 1;
714         }
715
716         public static int test_0_marshal_array_delegate_null () {       
717                 return mono_test_marshal_array_delegate1 (null, 0, new ArrayDelegate1 (array_delegate2));
718         }
719
720         public delegate int ArrayDelegate3 (int i, 
721                                                                                 string j, 
722                                                                                 [In, MarshalAs(UnmanagedType.LPArray, 
723                                                                                                            ArraySubType=UnmanagedType.LPStr, SizeParamIndex=3)] string[] arr);
724
725         [DllImport ("libtest", EntryPoint="mono_test_marshal_array_delegate")]
726         public static extern int mono_test_marshal_array_delegate3 (string[] arr, int len, ArrayDelegate3 d);
727
728         public static int array_delegate3 (int i, string j, string[] arr) {
729                 return (arr == null) ? 0 : 1;
730         }
731
732         public static int test_0_marshal_array_delegate_bad_paramindex () {
733                 try {
734                         mono_test_marshal_array_delegate3 (null, 0, new ArrayDelegate3 (array_delegate3));
735                         return 1;
736                 }
737                 catch (MarshalDirectiveException) {
738                         return 0;
739                 }
740         }
741
742         public delegate int ArrayDelegate4 (int i, 
743                                                                                 string j, 
744                                                                                 [In, MarshalAs(UnmanagedType.LPArray, 
745                                                                                                            ArraySubType=UnmanagedType.LPStr, SizeParamIndex=1)] string[] arr);
746
747         [DllImport ("libtest", EntryPoint="mono_test_marshal_array_delegate")]
748         public static extern int mono_test_marshal_array_delegate4 (string[] arr, int len, ArrayDelegate4 d);
749
750         public static int array_delegate4 (int i, string j, string[] arr) {
751                 return (arr == null) ? 0 : 1;
752         }
753
754         public static int test_0_marshal_array_delegate_bad_paramtype () {
755                 try {
756                         mono_test_marshal_array_delegate4 (null, 0, new ArrayDelegate4 (array_delegate4));
757                         return 1;
758                 }
759                 catch (MarshalDirectiveException) {
760                         return 0;
761                 }
762         }
763
764         public delegate int ArrayDelegate4_2 (int i, 
765                                                                                 string j, 
766                                                                                   string[] arr);
767
768         [DllImport ("libtest", EntryPoint="mono_test_marshal_array_delegate")]
769         public static extern int mono_test_marshal_array_delegate4_2 (string[] arr, int len, ArrayDelegate4_2 d);
770
771         public static int array_delegate4_2 (int i, string j, string[] arr) {
772                 return (arr == null) ? 0 : 1;
773         }
774
775         public static int test_0_marshal_array_delegate_no_marshal_directive () {
776                 try {
777                         mono_test_marshal_array_delegate4_2 (null, 0, new ArrayDelegate4_2 (array_delegate4_2));
778                         return 1;
779                 }
780                 catch (MarshalDirectiveException) {
781                         return 0;
782                 }
783         }
784
785         public delegate int ArrayDelegate4_3 (int i, 
786                                                                                 string j, 
787                                                                                   string[] arr);
788
789         [DllImport ("libtest", EntryPoint="mono_test_marshal_array_delegate")]
790         public static extern int mono_test_marshal_array_delegate4_3 (string[] arr, int len, ArrayDelegate4_3 d);
791
792         public int array_delegate4_3 (int i, string j, string[] arr) {
793                 return (arr == null) ? 0 : 1;
794         }
795
796         public static int test_0_marshal_array_delegate_no_marshal_directive_instance () {
797                 try {
798                         Tests t = new Tests ();
799                         mono_test_marshal_array_delegate4_3 (null, 0, new ArrayDelegate4_3 (t.array_delegate4_3));
800                         return 1;
801                 }
802                 catch (MarshalDirectiveException) {
803                         return 0;
804                 }
805         }
806
807         public delegate int ArrayDelegate5 (int i, 
808                                                                                 string j, 
809                                                                                 [In, MarshalAs(UnmanagedType.LPArray, 
810                                                                                                            ArraySubType=UnmanagedType.LPWStr, SizeParamIndex=0)] string[] arr);
811
812         [DllImport ("libtest", EntryPoint="mono_test_marshal_array_delegate", CharSet=CharSet.Unicode)]
813         public static extern int mono_test_marshal_array_delegate5 (string[] arr, int len, ArrayDelegate5 d);
814
815         public static int array_delegate5 (int i, string j, string[] arr) {
816                 if (arr.Length != 2)
817                         return 1;
818                 if ((arr [0] != "ABC") || (arr [1] != "DEF"))
819                         return 2;
820                 return 0;
821         }
822
823         public static int test_0_marshal_array_delegate_unicode_string () {     
824                 string[] arr = new string [] { "ABC", "DEF" };
825                 return mono_test_marshal_array_delegate5 (arr, arr.Length, new ArrayDelegate5 (array_delegate5));
826         }
827
828         public delegate int ArrayDelegate6 (int i, 
829                                                                                 string j, 
830                                                                                 [In, MarshalAs(UnmanagedType.LPArray, 
831                                                                                                            ArraySubType=UnmanagedType.LPStr, SizeConst=2)] string[] arr);
832
833         [DllImport ("libtest", EntryPoint="mono_test_marshal_array_delegate")]
834         public static extern int mono_test_marshal_array_delegate6 (string[] arr, int len, ArrayDelegate6 d);
835
836         public static int array_delegate6 (int i, string j, string[] arr) {
837                 if (arr.Length != 2)
838                         return 1;
839                 if ((arr [0] != "ABC") || (arr [1] != "DEF"))
840                         return 2;
841                 return 0;
842         }
843
844         public static int test_0_marshal_array_delegate_sizeconst () {  
845                 string[] arr = new string [] { "ABC", "DEF" };
846                 return mono_test_marshal_array_delegate6 (arr, 1024, new ArrayDelegate6 (array_delegate6));
847         }
848
849         public delegate int ArrayDelegate7 (int i, 
850                                                                                 string j, 
851                                                                                 [In, MarshalAs(UnmanagedType.LPArray, 
852                                                                                                            ArraySubType=UnmanagedType.LPStr, SizeConst=1, SizeParamIndex=0)] string[] arr);
853
854         [DllImport ("libtest", EntryPoint="mono_test_marshal_array_delegate")]
855         public static extern int mono_test_marshal_array_delegate7 (string[] arr, int len, ArrayDelegate7 d);
856
857         public static int array_delegate7 (int i, string j, string[] arr) {
858                 if (arr.Length != 2)
859                         return 1;
860                 if ((arr [0] != "ABC") || (arr [1] != "DEF"))
861                         return 2;
862                 return 0;
863         }
864
865         public static int test_0_marshal_array_delegate_sizeconst_paramindex () {       
866                 string[] arr = new string [] { "ABC", "DEF" };
867                 return mono_test_marshal_array_delegate7 (arr, 1, new ArrayDelegate7 (array_delegate7));
868         }
869
870         public delegate int ArrayDelegate8 (int i, string j,
871                                                                                 [In, MarshalAs(UnmanagedType.LPArray, 
872                                                                                 SizeParamIndex=0)] 
873                                                                                 int[] arr);
874
875         [DllImport ("libtest", EntryPoint="mono_test_marshal_array_delegate")]
876         public static extern int mono_test_marshal_array_delegate8 (int[] arr, int len, ArrayDelegate8 d);
877
878         public static int array_delegate8 (int i, string j, int[] arr) {
879                 if (arr.Length != 2)
880                         return 1;
881                 if ((arr [0] != 42) || (arr [1] != 43))
882                         return 2;
883                 return 0;
884         }
885
886         public static int test_0_marshal_array_delegate_blittable () {  
887                 int[] arr = new int [] { 42, 43 };
888                 return mono_test_marshal_array_delegate8 (arr, 2, new ArrayDelegate8 (array_delegate8));
889         }
890
891         /* Array with size param of type long */
892
893         public delegate int ArrayDelegate8_2 (long i, 
894                                                                                 string j, 
895                                                                                 [In, MarshalAs(UnmanagedType.LPArray, 
896                                                                                                            ArraySubType=UnmanagedType.LPStr, SizeParamIndex=0)] string[] arr);
897
898         [DllImport ("libtest", EntryPoint="mono_test_marshal_array_delegate_long")]
899         public static extern int mono_test_marshal_array_delegate8_2 (string[] arr, long len, ArrayDelegate8_2 d);
900
901         public static int array_delegate8_2 (long i, string j, string[] arr) {
902                 if (arr.Length != 2)
903                         return 1;
904                 if ((arr [0] != "ABC") || (arr [1] != "DEF"))
905                         return 2;
906                 return 0;
907         }
908
909         public static int test_0_marshal_array_delegate_long_param () { 
910                 string[] arr = new string [] { "ABC", "DEF" };
911                 return mono_test_marshal_array_delegate8_2 (arr, arr.Length, new ArrayDelegate8_2 (array_delegate8_2));
912         }
913
914
915         /*
916          * [Out] blittable arrays
917          */
918
919         public delegate int ArrayDelegate9 (int i, string j,
920                                                                                 [Out, MarshalAs(UnmanagedType.LPArray, 
921                                                                                 SizeParamIndex=0)] 
922                                                                                 int[] arr);
923
924         [DllImport ("libtest", EntryPoint="mono_test_marshal_out_array_delegate")]
925         public static extern int mono_test_marshal_out_array_delegate (int[] arr, int len, ArrayDelegate9 d);
926
927         public static int array_delegate9 (int i, string j, int[] arr) {
928                 if (arr.Length != 2)
929                         return 1;
930
931                 arr [0] = 1;
932                 arr [1] = 2;
933
934                 return 0;
935         }
936
937         public static int test_0_marshal_out_array_delegate () {        
938                 int[] arr = new int [] { 42, 43 };
939                 return mono_test_marshal_out_array_delegate (arr, 2, new ArrayDelegate9 (array_delegate9));
940         }
941
942         /*
943          * [Out] string arrays
944          */
945
946         public delegate int ArrayDelegate10 (int i, 
947                                                                                  string j, 
948                                                                                  [Out, MarshalAs(UnmanagedType.LPArray, 
949                                                                                                                  ArraySubType=UnmanagedType.LPStr, SizeConst=2)] string[] arr);
950
951         [DllImport ("libtest", EntryPoint="mono_test_marshal_out_string_array_delegate")]
952         public static extern int mono_test_marshal_out_string_array_delegate (string[] arr, int len, ArrayDelegate10 d);
953
954         public static int array_delegate10 (int i, string j, string[] arr) {
955                 if (arr.Length != 2)
956                         return 1;
957
958                 arr [0] = "ABC";
959                 arr [1] = "DEF";
960
961                 return 0;
962         }
963
964         public static int test_0_marshal_out_string_array_delegate () { 
965                 string[] arr = new string [] { "", "" };
966                 return mono_test_marshal_out_string_array_delegate (arr, 2, new ArrayDelegate10 (array_delegate10));
967         }
968
969         /*
970          * [In, Out] classes
971          */
972
973         public delegate int InOutByvalClassDelegate ([In, Out] SimpleClass ss);
974
975         [DllImport ("libtest", EntryPoint="mono_test_marshal_inout_byval_class_delegate")]
976         public static extern int mono_test_marshal_inout_byval_class_delegate (InOutByvalClassDelegate d);
977
978         public static int delegate_test_byval_class_inout (SimpleClass ss) {
979                 if ((ss.a != false) || (ss.b != true) || (ss.c != false) || (ss.d != "FOO"))
980                         return 1;
981
982                 ss.a = true;
983                 ss.b = false;
984                 ss.c = true;
985                 ss.d = "RES";
986
987                 return 0;
988         }
989
990         public static int test_0_marshal_inout_byval_class_delegate () {
991                 return mono_test_marshal_inout_byval_class_delegate (new InOutByvalClassDelegate (delegate_test_byval_class_inout));
992         }
993
994         /*
995          * Returning unicode strings
996          */
997         [return: MarshalAs(UnmanagedType.LPWStr)]
998         public delegate string ReturnUnicodeStringDelegate([MarshalAs(UnmanagedType.LPWStr)] string message);
999
1000         [DllImport ("libtest", EntryPoint="mono_test_marshal_return_unicode_string_delegate")]
1001         public static extern int mono_test_marshal_return_unicode_string_delegate (ReturnUnicodeStringDelegate d);
1002
1003         public static String return_unicode_string_delegate (string message) {
1004                 return message;
1005         }
1006
1007         public static int test_0_marshal_return_unicode_string_delegate () {    
1008                 return mono_test_marshal_return_unicode_string_delegate (new ReturnUnicodeStringDelegate (return_unicode_string_delegate));
1009         }
1010
1011         /*
1012          * Returning string arrays
1013          */
1014         public delegate string[] ReturnArrayDelegate (int i);
1015
1016         [DllImport ("libtest", EntryPoint="mono_test_marshal_return_string_array_delegate")]
1017         public static extern int mono_test_marshal_return_string_array_delegate (ReturnArrayDelegate d);
1018
1019         public static String[] return_array_delegate (int i) {
1020                 String[] arr = new String [2];
1021
1022                 arr [0] = "ABC";
1023                 arr [1] = "DEF";
1024
1025                 return arr;
1026         }
1027
1028         public static String[] return_array_delegate_null (int i) {
1029                 return null;
1030         }
1031
1032         public static int test_0_marshal_return_string_array_delegate () {      
1033                 return mono_test_marshal_return_string_array_delegate (new ReturnArrayDelegate (return_array_delegate));
1034         }
1035
1036         public static int test_3_marshal_return_string_array_delegate_null () { 
1037                 return mono_test_marshal_return_string_array_delegate (new ReturnArrayDelegate (return_array_delegate_null));
1038         }
1039
1040         /*
1041          * Byref string marshalling
1042          */
1043         public delegate int ByrefStringDelegate (ref string s);
1044
1045         [DllImport ("libtest", EntryPoint="mono_test_marshal_byref_string_delegate")]
1046         public static extern int mono_test_marshal_byref_string_delegate (ByrefStringDelegate d);
1047
1048         public static int byref_string_delegate (ref string s) {
1049                 if (s != "ABC")
1050                         return 1;
1051
1052                 s = "DEF";
1053
1054                 return 0;
1055         }
1056
1057         public static int test_0_marshal_byref_string_delegate () {     
1058                 return mono_test_marshal_byref_string_delegate (new ByrefStringDelegate (byref_string_delegate));
1059         }
1060
1061         /*
1062          * Thread attach
1063          */
1064
1065         public delegate int SimpleDelegate (int i);
1066
1067         [DllImport ("libtest", EntryPoint="mono_test_marshal_thread_attach")]
1068         public static extern int mono_test_marshal_thread_attach (SimpleDelegate d);
1069
1070         public static int test_43_thread_attach () {
1071                 int res = mono_test_marshal_thread_attach (delegate (int i) {
1072                                 if (!Thread.CurrentThread.IsBackground)
1073                                         return 0;
1074                                 return i + 1;
1075                         });
1076                 return res;
1077         }
1078
1079         /*
1080          * Appdomain save/restore
1081          */
1082     static Func<int> callback;
1083
1084         [DllImport ("libtest", EntryPoint="mono_test_marshal_set_callback")]
1085         public static extern int mono_test_marshal_set_callback (Func<int> a);
1086
1087         [DllImport ("libtest", EntryPoint="mono_test_marshal_call_callback")]
1088         public static extern int mono_test_marshal_call_callback ();
1089
1090         public static int test_0_appdomain_switch () {
1091                 // FIXME: The appdomain unload hangs
1092                 //return 0;
1093         AppDomain ad = AppDomain.CreateDomain ("foo");
1094                 var c = (CallbackClass)ad.CreateInstanceAndUnwrap (
1095                                 typeof (CallbackClass).Assembly.FullName, "Tests/CallbackClass");
1096                 c.SetCallback ();
1097                 int domain_id = AppDomain.CurrentDomain.Id;
1098                 int new_id = mono_test_marshal_call_callback ();
1099                 int res = 0;
1100                 if (new_id == domain_id)
1101                         res = 1;
1102                 if (AppDomain.CurrentDomain.Id != domain_id)
1103                         res = 2;
1104                 AppDomain.Unload (ad);
1105                 return res;
1106     }
1107
1108         static int domain_callback () {
1109                 return AppDomain.CurrentDomain.Id;
1110         }
1111
1112         class CallbackClass : MarshalByRefObject {
1113                 public int SetCallback () {
1114                         mono_test_marshal_set_callback (domain_callback);
1115                         return 0;
1116                 }
1117     }
1118 }