2004-06-05 Gonzalo Paniagua Javier <gonzalo@ximian.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.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         }
19
20         [StructLayout (LayoutKind.Sequential)]
21         public class SimpleClass {
22                 public bool a;
23                 public bool b;
24                 public bool c;
25                 public string d;
26         }
27
28         public static SimpleStruct delegate_test_struct (SimpleStruct ss)
29         {
30                 SimpleStruct res;
31
32                 res.a = !ss.a;
33                 res.b = !ss.b;
34                 res.c = !ss.c;
35                 res.d = ss.d + "-RES";
36
37                 return res;
38         }
39
40         public static int delegate_test_struct_byref (int a, ref SimpleStruct ss, int b)
41         {
42                 if (a == 1 && b == 2 && ss.a && !ss.b && ss.c && ss.d == "TEST2") {
43                         ss.a = true;
44                         ss.b = true;
45                         ss.c = true;
46                         ss.d = "TEST3";
47                         return 0;
48                 }
49
50                 return 1;
51         }
52
53         public static int delegate_test_struct_out (int a, out SimpleStruct ss, int b)
54         {
55                 ss.a = true;
56                 ss.b = true;
57                 ss.c = true;
58                 ss.d = "TEST3";
59
60                 return 0;
61         }
62
63         public static SimpleClass delegate_test_class (SimpleClass ss)
64         {
65                 if (ss == null)
66                         return null;
67
68                 if (! (!ss.a && ss.b && !ss.c && ss.d == "TEST"))
69                         return null;
70
71                 SimpleClass res = ss;
72
73                 return res;
74         }
75
76         public static int delegate_test_class_byref (ref SimpleClass ss)
77         {
78                 if (ss == null)
79                         return -1;
80
81                 if (!ss.a && ss.b && !ss.c && ss.d == "TEST") {
82                         ss.a = true;
83                         ss.b = false;
84                         ss.c = true;
85                         ss.d = "RES";
86
87                         return 0;
88                 }
89
90                 return 1;
91         }
92
93         public static int delegate_test_class_out (out SimpleClass ss)
94         {
95                 ss = new SimpleClass ();
96                 ss.a = true;
97                 ss.b = false;
98                 ss.c = true;
99                 ss.d = "RES";
100
101                 return 0;
102         }
103
104         public static int delegate_test_primitive_byref (ref int i)
105         {
106                 if (i != 1)
107                         return 1;
108                 
109                 i = 2;
110                 return 0;
111         }
112
113         public static int delegate_test_string_marshalling (string s)
114         {
115                 return s == "ABC" ? 0 : 1;
116         }
117
118         [DllImport ("libtest", EntryPoint="mono_test_ref_vtype")]
119         public static extern int mono_test_ref_vtype (int a, ref SimpleStruct ss, int b, TestDelegate d);
120
121         public delegate int OutStructDelegate (int a, out SimpleStruct ss, int b);
122
123         [DllImport ("libtest", EntryPoint="mono_test_marshal_out_struct")]
124         public static extern int mono_test_marshal_out_struct (int a, out SimpleStruct ss, int b, OutStructDelegate d);
125         
126         [DllImport ("libtest", EntryPoint="mono_test_marshal_delegate2")]
127         public static extern int mono_test_marshal_delegate2 (SimpleDelegate2 d);
128
129         [DllImport ("libtest", EntryPoint="mono_test_marshal_delegate4")]
130         public static extern int mono_test_marshal_delegate4 (SimpleDelegate4 d);
131
132         [DllImport ("libtest", EntryPoint="mono_test_marshal_delegate5")]
133         public static extern int mono_test_marshal_delegate5 (SimpleDelegate5 d);
134
135         [DllImport ("libtest", EntryPoint="mono_test_marshal_delegate6")]
136         public static extern int mono_test_marshal_delegate6 (SimpleDelegate5 d);
137
138         [DllImport ("libtest", EntryPoint="mono_test_marshal_delegate7")]
139         public static extern int mono_test_marshal_delegate7 (SimpleDelegate7 d);
140
141         [DllImport ("libtest", EntryPoint="mono_test_marshal_delegate8", CharSet=CharSet.Unicode)]
142         public static extern int mono_test_marshal_delegate8 (SimpleDelegate8 d, string s);
143
144         [DllImport ("libtest", EntryPoint="mono_test_marshal_delegate9")]
145         public static extern int mono_test_marshal_delegate9 (SimpleDelegate9 d, return_int_delegate d2);
146
147         [DllImport ("libtest", EntryPoint="mono_test_marshal_delegate10")]
148         public static extern int mono_test_marshal_delegate10 (SimpleDelegate9 d);
149
150         [DllImport ("libtest", EntryPoint="mono_test_marshal_primitive_byref_delegate")]
151         public static extern int mono_test_marshal_primitive_byref_delegate (PrimitiveByrefDelegate d);
152
153         public delegate int TestDelegate (int a, ref SimpleStruct ss, int b);
154
155         public delegate SimpleStruct SimpleDelegate2 (SimpleStruct ss);
156
157         public delegate SimpleClass SimpleDelegate4 (SimpleClass ss);
158
159         public delegate int SimpleDelegate5 (ref SimpleClass ss);
160
161         public delegate int SimpleDelegate7 (out SimpleClass ss);
162
163         public delegate int SimpleDelegate8 ([MarshalAs (UnmanagedType.LPWStr)] string s1);
164
165         public delegate int return_int_delegate (int i);
166
167         public delegate int SimpleDelegate9 (return_int_delegate del);
168
169         public delegate int PrimitiveByrefDelegate (ref int i);
170
171         public static int Main () {
172                 return TestDriver.RunTests (typeof (Tests));
173         }
174
175         /* Test structures as arguments and return values of delegates */
176         static int test_0_marshal_struct_delegate () {
177                 SimpleDelegate2 d = new SimpleDelegate2 (delegate_test_struct);
178
179                 return mono_test_marshal_delegate2 (d);
180         }
181
182         /* Test structures as byref arguments of delegates */
183         static int test_0_marshal_byref_struct_delegate () {
184                 SimpleStruct ss = new SimpleStruct ();
185                 TestDelegate d = new TestDelegate (delegate_test_struct_byref);
186                 
187                 ss.b = true;
188                 ss.d = "TEST1";
189
190                 if (mono_test_ref_vtype (1, ref ss, 2, d) != 0)
191                         return 1;
192
193                 if (! (ss.a && ss.b && ss.c && ss.d == "TEST3"))
194                         return 2;
195                 
196                 return 0;
197         }
198
199         /* Test structures as out arguments of delegates */
200         static int test_0_marshal_out_struct_delegate () {
201                 SimpleStruct ss = new SimpleStruct ();
202                 OutStructDelegate d = new OutStructDelegate (delegate_test_struct_out);
203
204                 return mono_test_marshal_out_struct (1, out ss, 2, d);
205         }
206
207         /* Test classes as arguments and return values of delegates */
208         static int test_0_marshal_class_delegate () {
209                 SimpleDelegate4 d = new SimpleDelegate4 (delegate_test_class);
210
211                 return mono_test_marshal_delegate4 (d);
212         }
213
214         /* Test classes as byref arguments of delegates */
215         static int test_0_marshal_byref_class_delegate () {
216                 SimpleDelegate5 d = new SimpleDelegate5 (delegate_test_class_byref);
217
218                 return mono_test_marshal_delegate5 (d);
219         }
220
221         /* Test classes as out arguments of delegates */
222         static int test_0_marshal_out_class_delegate () {
223                 SimpleDelegate7 d = new SimpleDelegate7 (delegate_test_class_out);
224
225                 return mono_test_marshal_delegate7 (d);
226         }
227
228         /* Test string marshalling with delegates */
229         static int test_0_marshal_string_delegate () {
230                 SimpleDelegate8 d = new SimpleDelegate8 (delegate_test_string_marshalling);
231
232                 return mono_test_marshal_delegate8 (d, "ABC");
233         }
234
235         /* Test that the delegate wrapper correctly catches null byref arguments */
236         static int test_0_marshal_byref_class_delegate_null () {
237                 SimpleDelegate5 d = new SimpleDelegate5 (delegate_test_class_byref);
238                 
239                 try {
240                         mono_test_marshal_delegate6 (d);
241                         return 1;
242                 }
243                 catch (ArgumentNullException ex) {
244                         return 0;
245                 }
246         }
247
248         static int return_self (int i) {
249                 return i;
250         }
251
252         static int call_int_delegate (return_int_delegate d) {
253                 return d (55);
254         }
255
256         static int test_55_marshal_delegate_delegate () {
257                 SimpleDelegate9 d = new SimpleDelegate9 (call_int_delegate);
258
259                 return mono_test_marshal_delegate9 (d, new return_int_delegate (return_self));
260         }
261
262         static int test_0_marshal_delegate_delegate_unmanaged_ftn () {
263                 SimpleDelegate9 d = new SimpleDelegate9 (call_int_delegate);
264
265                 try {
266                         mono_test_marshal_delegate10 (d);
267                         return 1;
268                 }
269                 catch (ArgumentException) {
270                         return 0;
271                 }
272
273                 return 2;
274         }
275
276         static int test_0_marshal_primitive_byref_delegate () {
277                 PrimitiveByrefDelegate d = new PrimitiveByrefDelegate (delegate_test_primitive_byref);
278
279                 return mono_test_marshal_primitive_byref_delegate (d);
280         }
281 }