2005-01-31 Zoltan Varga <vargaz@freemail.hu>
[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         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         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         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         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         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         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         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         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         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         static int test_0_marshal_delegate_delegate_unmanaged_ftn () {
272                 SimpleDelegate9 d = new SimpleDelegate9 (call_int_delegate);
273
274                 try {
275                         mono_test_marshal_delegate10 (d);
276                         return 1;
277                 }
278                 catch (ArgumentException) {
279                         return 0;
280                 }
281
282                 return 2;
283         }
284
285         static int test_0_marshal_primitive_byref_delegate () {
286                 PrimitiveByrefDelegate d = new PrimitiveByrefDelegate (delegate_test_primitive_byref);
287
288                 return mono_test_marshal_primitive_byref_delegate (d);
289         }
290
291         public static return_int_delegate return_delegate () {
292                 return new return_int_delegate (return_self);
293         }
294
295         static int test_55_marshal_return_delegate_delegate () {
296                 return mono_test_marshal_return_delegate_delegate (new ReturnDelegateDelegate (return_delegate));
297         }
298
299         /* Passing and returning strings */
300
301         public delegate String ReturnStringDelegate (String s);
302
303         [DllImport ("libtest", EntryPoint="mono_test_return_string")]
304         public static extern String mono_test_marshal_return_string_delegate (ReturnStringDelegate d);
305
306         public static String managed_return_string (String s) {
307                 if (s != "TEST")
308                         return "";
309                 else
310                         return "12345";
311         }
312
313         static int test_0_marshal_return_string_delegate () {
314                 ReturnStringDelegate d = new ReturnStringDelegate (managed_return_string);
315                 String s = mono_test_marshal_return_string_delegate (d);
316
317                 return (s == "12345") ? 0 : 1;
318         }
319
320         /* Passing and returning enums */
321
322         public enum FooEnum {
323                 Foo1,
324                 Foo2,
325                 Foo3
326         };
327
328         public delegate FooEnum ReturnEnumDelegate (FooEnum e);
329
330         [DllImport ("libtest", EntryPoint="mono_test_marshal_return_enum_delegate")]
331         public static extern int mono_test_marshal_return_enum_delegate (ReturnEnumDelegate d);
332
333         public static FooEnum managed_return_enum (FooEnum e) {
334                 return (FooEnum)((int)e + 1);
335         }
336
337         static int test_0_marshal_return_enum_delegate () {
338                 ReturnEnumDelegate d = new ReturnEnumDelegate (managed_return_enum);
339                 FooEnum e = (FooEnum)mono_test_marshal_return_enum_delegate (d);
340
341                 return e == FooEnum.Foo3 ? 0 : 1;
342         }
343
344         /* Passing and returning blittable structs */
345
346         [StructLayout (LayoutKind.Sequential)]
347         public struct BlittableStruct {
348                 public int a, b, c;
349                 public long d;
350         }
351
352         public static BlittableStruct delegate_test_blittable_struct (BlittableStruct ss)
353         {
354                 BlittableStruct res;
355
356                 res.a = -ss.a;
357                 res.b = -ss.b;
358                 res.c = -ss.c;
359                 res.d = -ss.d;
360
361                 return res;
362         }
363
364         public delegate BlittableStruct SimpleDelegate10 (BlittableStruct ss);
365
366         [DllImport ("libtest", EntryPoint="mono_test_marshal_blittable_struct_delegate")]
367         public static extern int mono_test_marshal_blittable_struct_delegate (SimpleDelegate10 d);
368
369         static int test_0_marshal_blittable_struct_delegate () {
370                 return mono_test_marshal_blittable_struct_delegate (new SimpleDelegate10 (delegate_test_blittable_struct));
371         }
372 }