c5c94aa9e421d376c2cb2adcbb4f6cd0913b4597
[mono.git] / mono / tests / pinvoke2.cs
1 using System;
2 using System.Text;
3 using System.Runtime.InteropServices;
4
5 public class Tests {
6
7         public static int delegate_test (int a)
8         {
9                 if (a == 2)
10                         return 0;
11
12                 return 1;
13         }
14         
15         [StructLayout (LayoutKind.Sequential)]
16         public struct SimpleStruct {
17                 public bool a;
18                 public bool b;
19                 public bool c;
20                 public string d;
21         }
22
23         [StructLayout (LayoutKind.Sequential)]
24         public struct SimpleStruct2 {
25                 public bool a;
26                 public bool b;
27                 public bool c;
28                 public string d;
29                 public byte e;
30                 public double f;
31                 public byte g;
32                 public long h;
33         }
34
35         [StructLayout (LayoutKind.Sequential, Size=0)]
36         public struct EmptyStruct {
37         }
38
39         /* sparcv9 has complex conventions when passing structs with doubles in them 
40            by value, some simple tests for them */
41         [StructLayout (LayoutKind.Sequential)]
42         public struct Point {
43                 public double x;
44                 public double y;
45         }
46
47         [StructLayout (LayoutKind.Sequential)]
48         public struct MixedPoint {
49                 public int x;
50                 public double y;
51         }
52
53         [StructLayout (LayoutKind.Sequential)]
54         public class SimpleClass {
55                 public bool a;
56                 public bool b;
57                 public bool c;
58                 public string d;
59                 public byte e;
60                 public double f;
61                 public byte g;
62                 public long h;
63         }
64
65         [StructLayout (LayoutKind.Sequential)]
66         public class EmptyClass {
67         }
68
69         [DllImport ("libnot-found", EntryPoint="not_found")]
70         public static extern int mono_library_not_found ();
71
72         [DllImport ("libtest", EntryPoint="not_found")]
73         public static extern int mono_entry_point_not_found ();
74
75         [DllImport ("libtest.dll", EntryPoint="mono_test_marshal_char")]
76         public static extern int mono_test_marshal_char_2 (char a1);
77
78         [DllImport ("libtest", EntryPoint="mono_test_marshal_char")]
79         public static extern int mono_test_marshal_char (char a1);
80
81         [DllImport ("libtest", EntryPoint="mono_test_marshal_char_array")]
82         public static extern int mono_test_marshal_char_array (char[] a1);
83
84         [DllImport ("libtest", EntryPoint="mono_test_marshal_bool_byref")]
85         public static extern int mono_test_marshal_bool_byref (int a, ref bool b, int c);
86
87         [DllImport ("libtest", EntryPoint="mono_test_marshal_array")]
88         public static extern int mono_test_marshal_array (int [] a1);
89
90         [DllImport ("libtest", EntryPoint="mono_test_marshal_empty_string_array")]
91         public static extern int mono_test_marshal_empty_string_array (string [] a1);
92
93         [DllImport ("libtest", EntryPoint="mono_test_marshal_string_array")]
94         public static extern int mono_test_marshal_string_array (string [] a1);
95
96         [DllImport ("libtest", EntryPoint="mono_test_marshal_unicode_string_array", CharSet=CharSet.Unicode)]
97         public static extern int mono_test_marshal_unicode_string_array (string [] a1, [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.LPStr)]string [] a2);
98
99         [DllImport ("libtest", EntryPoint="mono_test_marshal_inout_array")]
100         public static extern int mono_test_marshal_inout_array ([In, Out] int [] a1);
101
102         [DllImport ("libtest", EntryPoint="mono_test_marshal_inout_nonblittable_array", CharSet = CharSet.Unicode)]
103         public static extern int mono_test_marshal_inout_nonblittable_array ([In, Out] char [] a1);
104         
105         [DllImport ("libtest", EntryPoint="mono_test_marshal_struct")]
106         public static extern int mono_test_marshal_struct (SimpleStruct ss);
107
108         [DllImport ("libtest", EntryPoint="mono_test_marshal_struct2")]
109         public static extern int mono_test_marshal_struct2 (SimpleStruct2 ss);
110
111         [DllImport ("libtest", EntryPoint="mono_test_marshal_struct2_2")]
112         public static extern int mono_test_marshal_struct2_2 (int i, int j, int k, SimpleStruct2 ss);
113
114         [DllImport ("libtest", EntryPoint="mono_test_marshal_point")]
115         public static extern int mono_test_marshal_point (Point p);
116
117         [DllImport ("libtest", EntryPoint="mono_test_marshal_mixed_point")]
118         public static extern int mono_test_marshal_mixed_point (MixedPoint p);
119
120         [DllImport ("libtest", EntryPoint="mono_test_empty_struct")]
121         public static extern int mono_test_empty_struct (int a, EmptyStruct es, int b);
122
123         [DllImport ("libtest", EntryPoint="mono_test_marshal_struct_array")]
124         public static extern int mono_test_marshal_struct_array (SimpleStruct2[] ss);
125
126         [DllImport ("libtest", EntryPoint="mono_test_marshal_class")]
127         public static extern SimpleClass mono_test_marshal_class (int i, int j, int k, SimpleClass ss, int l);
128
129         [DllImport ("libtest", EntryPoint="mono_test_marshal_byref_class")]
130         public static extern int mono_test_marshal_byref_class (ref SimpleClass ss);
131
132         [DllImport ("libtest", EntryPoint="mono_test_marshal_delegate")]
133         public static extern int mono_test_marshal_delegate (SimpleDelegate d);
134
135         [DllImport ("libtest", EntryPoint="mono_test_return_vtype")]
136         public static extern SimpleStruct mono_test_return_vtype (IntPtr i);
137
138         [DllImport ("libtest", EntryPoint="mono_test_marshal_stringbuilder")]
139         public static extern void mono_test_marshal_stringbuilder (StringBuilder sb, int len);
140
141         [DllImport ("libtest", EntryPoint="mono_test_marshal_stringbuilder_unicode", CharSet=CharSet.Unicode)]
142         public static extern void mono_test_marshal_stringbuilder_unicode (StringBuilder sb, int len);
143
144         [DllImport ("libtest", EntryPoint="mono_test_last_error", SetLastError=true)]
145         public static extern void mono_test_last_error (int err);
146
147         public delegate int SimpleDelegate (int a);
148
149         public static int Main () {
150                 return TestDriver.RunTests (typeof (Tests));
151         }
152
153         static int test_0_marshal_char () {
154                 return mono_test_marshal_char ('a');
155         }
156
157         static int test_0_marshal_char_array () {
158                 // char[] is implicitly marshalled as [Out]
159                 char[] buf = new char [32];
160                 mono_test_marshal_char_array (buf);
161                 string s = new string (buf);
162                 if (s.StartsWith ("abcdef"))
163                         return 0;
164                 else
165                         return 1;
166         }
167
168         static int test_1225_marshal_array () {
169                 int [] a1 = new int [50];
170                 for (int i = 0; i < 50; i++)
171                         a1 [i] = i;
172
173                 return mono_test_marshal_array (a1);
174         }
175
176         static int test_1225_marshal_inout_array () {
177                 int [] a1 = new int [50];
178                 for (int i = 0; i < 50; i++)
179                         a1 [i] = i;
180
181                 int res = mono_test_marshal_inout_array (a1);
182
183                 for (int i = 0; i < 50; i++)
184                         if (a1 [i] != 50 - i) {
185                                 Console.WriteLine ("X: " + i + " " + a1 [i]);
186                                 return 2;
187                         }
188
189                 return res;
190         }
191
192         static int test_0_marshal_inout_nonblittable_array () {
193                 char [] a1 = new char [10];
194                 for (int i = 0; i < 10; i++)
195                         a1 [i] = "Hello, World" [i];
196
197                 int res = mono_test_marshal_inout_nonblittable_array (a1);
198
199                 for (int i = 0; i < 10; i++)
200                         if (a1 [i] != 'F')
201                                 return 2;
202
203                 return res;
204         }
205
206         static int test_0_marshal_struct () {
207                 SimpleStruct ss = new  SimpleStruct ();
208                 ss.b = true;
209                 ss.d = "TEST";
210                 
211                 return mono_test_marshal_struct (ss);
212         }
213
214         static int test_0_marshal_struct2 () {
215                 SimpleStruct2 ss2 = new  SimpleStruct2 ();
216                 ss2.b = true;
217                 ss2.d = "TEST";
218                 ss2.e = 99;
219                 ss2.f = 1.5;
220                 ss2.g = 42;
221                 ss2.h = 123L;
222
223                 return mono_test_marshal_struct2 (ss2);
224         }
225
226         static int test_0_marshal_struct3 () {
227                 SimpleStruct2 ss2 = new  SimpleStruct2 ();
228                 ss2.b = true;
229                 ss2.d = "TEST";
230                 ss2.e = 99;
231                 ss2.f = 1.5;
232                 ss2.g = 42;
233                 ss2.h = 123L;
234
235                 return mono_test_marshal_struct2_2 (10, 11, 12, ss2);
236         }
237
238         static int test_0_marshal_empty_struct () {
239                 EmptyStruct es = new EmptyStruct ();
240
241                 if (mono_test_empty_struct (1, es, 2) != 0)
242                         return 1;
243                 
244                 return 0;
245         }
246
247         static int test_0_marshal_struct_array () {
248                 SimpleStruct2[] ss_arr = new SimpleStruct2 [2];
249
250                 SimpleStruct2 ss2 = new SimpleStruct2 ();
251                 ss2.b = true;
252                 ss2.d = "TEST";
253                 ss2.e = 99;
254                 ss2.f = 1.5;
255                 ss2.g = 42;
256                 ss2.h = 123L;
257
258                 ss_arr [0] = ss2;
259
260                 ss2.b = false;
261                 ss2.d = "TEST2";
262                 ss2.e = 100;
263                 ss2.f = 2.5;
264                 ss2.g = 43;
265                 ss2.h = 124L;
266
267                 ss_arr [1] = ss2;
268
269                 return mono_test_marshal_struct_array (ss_arr);
270         }
271
272         /* Test classes as arguments and return values */
273         static int test_0_marshal_class () {
274                 SimpleClass ss = new  SimpleClass ();
275                 ss.b = true;
276                 ss.d = "TEST";
277                 ss.e = 99;
278                 ss.f = 1.5;
279                 ss.g = 42;
280                 ss.h = 123L;
281
282                 SimpleClass res = mono_test_marshal_class (10, 11, 12, ss, 14);
283                 if (res == null)
284                         return 1;
285                 if  (! (res.a == ss.a && res.b == ss.b && res.c == ss.c && 
286                                 res.d == ss.d && res.e == ss.e && res.f == ss.f &&
287                                 res.g == ss.g && res.h == ss.h))
288                         return 2;
289
290                 /* Test null arguments and results */
291                 res = mono_test_marshal_class (10, 11, 12, null, 14);
292                 if (res != null)
293                         return 3;
294
295                 return 0;
296         }
297
298         static int test_0_marshal_byref_class () {
299                 SimpleClass ss = new  SimpleClass ();
300                 ss.b = true;
301                 ss.d = "TEST";
302                 ss.e = 99;
303                 ss.f = 1.5;
304                 ss.g = 42;
305                 ss.h = 123L;
306
307                 int res = mono_test_marshal_byref_class (ref ss);
308                 if (ss.d != "TEST-RES")
309                         return 1;
310
311                 return 0;
312         }
313
314         static int test_0_marshal_delegate () {
315                 SimpleDelegate d = new SimpleDelegate (delegate_test);
316
317                 return mono_test_marshal_delegate (d);
318         }
319
320         static int test_0_marshal_point () {
321                 Point pt = new Point();
322                 pt.x = 1.25;
323                 pt.y = 3.5;
324                 
325                 return mono_test_marshal_point(pt);
326         }
327
328         static int test_0_marshal_mixed_point () {
329                 MixedPoint mpt = new MixedPoint();
330                 mpt.x = 5;
331                 mpt.y = 6.75;
332                 
333                 return mono_test_marshal_mixed_point(mpt);
334         }
335
336         static int test_0_marshal_bool_byref () {
337                 bool b = true;
338                 if (mono_test_marshal_bool_byref (99, ref b, 100) != 1)
339                         return 1;
340                 b = false;
341                 if (mono_test_marshal_bool_byref (99, ref b, 100) != 0)
342                         return 12;
343                 if (b != true)
344                         return 13;
345
346                 return 0;
347         }
348
349         static int test_0_return_vtype () {
350                 SimpleStruct ss = mono_test_return_vtype (new IntPtr (5));
351
352                 if (!ss.a && ss.b && !ss.c && ss.d == "TEST")
353                         return 0;
354                 
355                 return 1;
356         }
357
358         static int test_0_marshal_stringbuilder () {
359                 StringBuilder sb = new StringBuilder(255);
360                 mono_test_marshal_stringbuilder (sb, sb.Capacity);
361                 String res = sb.ToString();
362
363                 if (res != "This is my message.  Isn't it nice?")
364                         return 1;  
365                 
366                 return 0;
367         }
368
369         static int test_0_marshal_stringbuilder_unicode () {
370                 StringBuilder sb = new StringBuilder(255);
371                 mono_test_marshal_stringbuilder_unicode (sb, sb.Capacity);
372                 String res = sb.ToString();
373
374                 if (res != "This is my message.  Isn't it nice?")
375                         return 1;  
376                 
377                 return 0;
378         }
379
380         static int test_0_marshal_empty_string_array () {
381                 return mono_test_marshal_empty_string_array (null);
382         }
383
384         static int test_0_marshal_string_array () {
385                 return mono_test_marshal_string_array (new String [] { "ABC", "DEF" });
386         }
387
388         static int test_0_marshal_unicode_string_array () {
389                 return mono_test_marshal_unicode_string_array (new String [] { "ABC", "DEF" }, new String [] { "ABC", "DEF" });
390         }
391
392         static int test_0_last_error () {
393                 mono_test_last_error (5);
394                 if (Marshal.GetLastWin32Error () == 5)
395                         return 0;
396                 else
397                         return 1;
398         }
399
400         static int test_0_library_not_found () {
401
402                 try {
403                         mono_entry_point_not_found ();
404                         return 1;
405                 }
406                 catch (EntryPointNotFoundException) {
407                 }
408
409                 return 0;
410         }
411
412         static int test_0_entry_point_not_found () {
413
414                 try {
415                         mono_library_not_found ();
416                         return 1;
417                 }
418                 catch (DllNotFoundException) {
419                 }
420
421                 return 0;
422         }
423
424         /* Check that the runtime trims .dll from the library name */
425         static int test_0_trim_dll_from_name () {
426
427                 mono_test_marshal_char_2 ('A');
428
429                 return 0;
430         }
431 }