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