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