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