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