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