2004-08-04 Bernie Solomon <bernard@ugsolutions.com>
[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         [StructLayout (LayoutKind.Sequential)]
40         public struct DelegateStruct {
41                 public int a;
42                 public SimpleDelegate del;
43                 [MarshalAs(UnmanagedType.FunctionPtr)] 
44                 public SimpleDelegate del2;
45         }
46
47         /* sparcv9 has complex conventions when passing structs with doubles in them 
48            by value, some simple tests for them */
49         [StructLayout (LayoutKind.Sequential)]
50         public struct Point {
51                 public double x;
52                 public double y;
53         }
54
55         [StructLayout (LayoutKind.Sequential)]
56         public struct MixedPoint {
57                 public int x;
58                 public double y;
59         }
60
61         [StructLayout (LayoutKind.Sequential)]
62         public class SimpleClass {
63                 public bool a;
64                 public bool b;
65                 public bool c;
66                 public string d;
67                 public byte e;
68                 public double f;
69                 public byte g;
70                 public long h;
71         }
72
73         [StructLayout (LayoutKind.Sequential)]
74         public class EmptyClass {
75         }
76
77         [StructLayout (LayoutKind.Sequential)]
78         public struct LongAlignStruct {
79                 public int a;
80                 public long b;
81                 public long c;
82         }
83
84         [DllImport ("libnot-found", EntryPoint="not_found")]
85         public static extern int mono_library_not_found ();
86
87         [DllImport ("libtest", EntryPoint="not_found")]
88         public static extern int mono_entry_point_not_found ();
89
90         [DllImport ("libtest.dll", EntryPoint="mono_test_marshal_char")]
91         public static extern int mono_test_marshal_char_2 (char a1);
92
93         [DllImport ("libtest", EntryPoint="mono_test_marshal_char")]
94         public static extern int mono_test_marshal_char (char a1);
95
96         [DllImport ("libtest", EntryPoint="mono_test_marshal_char_array")]
97         public static extern int mono_test_marshal_char_array (char[] a1);
98
99         [DllImport ("libtest", EntryPoint="mono_test_marshal_bool_byref")]
100         public static extern int mono_test_marshal_bool_byref (int a, ref bool b, int c);
101
102         [DllImport ("libtest", EntryPoint="mono_test_marshal_array")]
103         public static extern int mono_test_marshal_array (int [] a1);
104
105         [DllImport ("libtest", EntryPoint="mono_test_marshal_empty_string_array")]
106         public static extern int mono_test_marshal_empty_string_array (string [] a1);
107
108         [DllImport ("libtest", EntryPoint="mono_test_marshal_string_array")]
109         public static extern int mono_test_marshal_string_array (string [] a1);
110
111         [DllImport ("libtest", EntryPoint="mono_test_marshal_unicode_string_array", CharSet=CharSet.Unicode)]
112         public static extern int mono_test_marshal_unicode_string_array (string [] a1, [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.LPStr)]string [] a2);
113
114         [DllImport ("libtest", EntryPoint="mono_test_marshal_stringbuilder_array")]
115         public static extern int mono_test_marshal_stringbuilder_array (StringBuilder [] a1);   
116
117         [DllImport ("libtest", EntryPoint="mono_test_marshal_inout_array")]
118         public static extern int mono_test_marshal_inout_array ([In, Out] int [] a1);
119
120         [DllImport ("libtest", EntryPoint="mono_test_marshal_inout_nonblittable_array", CharSet = CharSet.Unicode)]
121         public static extern int mono_test_marshal_inout_nonblittable_array ([In, Out] char [] a1);
122         
123         [DllImport ("libtest", EntryPoint="mono_test_marshal_struct")]
124         public static extern int mono_test_marshal_struct (SimpleStruct ss);
125
126         [DllImport ("libtest", EntryPoint="mono_test_marshal_struct2")]
127         public static extern int mono_test_marshal_struct2 (SimpleStruct2 ss);
128
129         [DllImport ("libtest", EntryPoint="mono_test_marshal_struct2_2")]
130         public static extern int mono_test_marshal_struct2_2 (int i, int j, int k, SimpleStruct2 ss);
131
132         [DllImport ("libtest", EntryPoint="mono_test_marshal_point")]
133         public static extern int mono_test_marshal_point (Point p);
134
135         [DllImport ("libtest", EntryPoint="mono_test_marshal_mixed_point")]
136         public static extern int mono_test_marshal_mixed_point (MixedPoint p);
137
138         [DllImport ("libtest", EntryPoint="mono_test_empty_struct")]
139         public static extern int mono_test_empty_struct (int a, EmptyStruct es, int b);
140
141         [DllImport ("libtest", EntryPoint="mono_test_marshal_struct_array")]
142         public static extern int mono_test_marshal_struct_array (SimpleStruct2[] ss);
143
144         [DllImport ("libtest", EntryPoint="mono_test_marshal_long_align_struct_array")]
145         public static extern int mono_test_marshal_long_align_struct_array (LongAlignStruct[] ss);
146
147         [DllImport ("libtest", EntryPoint="mono_test_marshal_class")]
148         public static extern SimpleClass mono_test_marshal_class (int i, int j, int k, SimpleClass ss, int l);
149
150         [DllImport ("libtest", EntryPoint="mono_test_marshal_byref_class")]
151         public static extern int mono_test_marshal_byref_class (ref SimpleClass ss);
152
153         [DllImport ("libtest", EntryPoint="mono_test_marshal_delegate")]
154         public static extern int mono_test_marshal_delegate (SimpleDelegate d);
155
156         [DllImport ("libtest", EntryPoint="mono_test_marshal_delegate_struct")]
157         public static extern int mono_test_marshal_delegate_struct (DelegateStruct d);
158
159         [DllImport ("libtest", EntryPoint="mono_test_return_vtype")]
160         public static extern SimpleStruct mono_test_return_vtype (IntPtr i);
161
162         [DllImport ("libtest", EntryPoint="mono_test_marshal_stringbuilder")]
163         public static extern void mono_test_marshal_stringbuilder (StringBuilder sb, int len);
164
165         [DllImport ("libtest", EntryPoint="mono_test_marshal_stringbuilder_unicode", CharSet=CharSet.Unicode)]
166         public static extern void mono_test_marshal_stringbuilder_unicode (StringBuilder sb, int len);
167
168         [DllImport ("libtest", EntryPoint="mono_test_last_error", SetLastError=true)]
169         public static extern void mono_test_last_error (int err);
170
171         [DllImport ("libtest", EntryPoint="mono_test_asany")]
172         public static extern int mono_test_asany ([MarshalAs (UnmanagedType.AsAny)] object o, int what);
173
174         [DllImport ("libtest", EntryPoint="mono_test_asany", CharSet=CharSet.Unicode)]
175         public static extern int mono_test_asany_unicode ([MarshalAs (UnmanagedType.AsAny)] object o, int what);
176
177         public delegate int SimpleDelegate (int a);
178
179         public static int Main () {
180                 return TestDriver.RunTests (typeof (Tests));
181         }
182
183         static int test_0_marshal_char () {
184                 return mono_test_marshal_char ('a');
185         }
186
187         static int test_0_marshal_char_array () {
188                 // char[] is implicitly marshalled as [Out]
189                 char[] buf = new char [32];
190                 mono_test_marshal_char_array (buf);
191                 string s = new string (buf);
192                 if (s.StartsWith ("abcdef"))
193                         return 0;
194                 else
195                         return 1;
196         }
197
198         static int test_1225_marshal_array () {
199                 int [] a1 = new int [50];
200                 for (int i = 0; i < 50; i++)
201                         a1 [i] = i;
202
203                 return mono_test_marshal_array (a1);
204         }
205
206         static int test_1225_marshal_inout_array () {
207                 int [] a1 = new int [50];
208                 for (int i = 0; i < 50; i++)
209                         a1 [i] = i;
210
211                 int res = mono_test_marshal_inout_array (a1);
212
213                 for (int i = 0; i < 50; i++)
214                         if (a1 [i] != 50 - i) {
215                                 Console.WriteLine ("X: " + i + " " + a1 [i]);
216                                 return 2;
217                         }
218
219                 return res;
220         }
221
222         static int test_0_marshal_inout_nonblittable_array () {
223                 char [] a1 = new char [10];
224                 for (int i = 0; i < 10; i++)
225                         a1 [i] = "Hello, World" [i];
226
227                 int res = mono_test_marshal_inout_nonblittable_array (a1);
228
229                 for (int i = 0; i < 10; i++)
230                         if (a1 [i] != 'F')
231                                 return 2;
232
233                 return res;
234         }
235
236         static int test_0_marshal_struct () {
237                 SimpleStruct ss = new  SimpleStruct ();
238                 ss.b = true;
239                 ss.d = "TEST";
240                 
241                 return mono_test_marshal_struct (ss);
242         }
243
244         static int test_0_marshal_struct2 () {
245                 SimpleStruct2 ss2 = new  SimpleStruct2 ();
246                 ss2.b = true;
247                 ss2.d = "TEST";
248                 ss2.e = 99;
249                 ss2.f = 1.5;
250                 ss2.g = 42;
251                 ss2.h = 123L;
252
253                 return mono_test_marshal_struct2 (ss2);
254         }
255
256         static int test_0_marshal_struct3 () {
257                 SimpleStruct2 ss2 = new  SimpleStruct2 ();
258                 ss2.b = true;
259                 ss2.d = "TEST";
260                 ss2.e = 99;
261                 ss2.f = 1.5;
262                 ss2.g = 42;
263                 ss2.h = 123L;
264
265                 return mono_test_marshal_struct2_2 (10, 11, 12, ss2);
266         }
267
268         static int test_0_marshal_empty_struct () {
269                 EmptyStruct es = new EmptyStruct ();
270
271                 if (mono_test_empty_struct (1, es, 2) != 0)
272                         return 1;
273                 
274                 return 0;
275         }
276
277         static int test_0_marshal_struct_array () {
278                 SimpleStruct2[] ss_arr = new SimpleStruct2 [2];
279
280                 SimpleStruct2 ss2 = new SimpleStruct2 ();
281                 ss2.b = true;
282                 ss2.d = "TEST";
283                 ss2.e = 99;
284                 ss2.f = 1.5;
285                 ss2.g = 42;
286                 ss2.h = 123L;
287
288                 ss_arr [0] = ss2;
289
290                 ss2.b = false;
291                 ss2.d = "TEST2";
292                 ss2.e = 100;
293                 ss2.f = 2.5;
294                 ss2.g = 43;
295                 ss2.h = 124L;
296
297                 ss_arr [1] = ss2;
298
299                 return mono_test_marshal_struct_array (ss_arr);
300         }
301
302         static int test_105_marshal_long_align_struct_array () {
303                 LongAlignStruct[] ss_arr = new LongAlignStruct [2];
304
305                 LongAlignStruct ss = new LongAlignStruct ();
306                 ss.a = 5;
307                 ss.b = 10;
308                 ss.c = 15;
309
310                 ss_arr [0] = ss;
311
312                 ss.a = 20;
313                 ss.b = 25;
314                 ss.c = 30;
315
316                 ss_arr [1] = ss;
317
318                 return mono_test_marshal_long_align_struct_array (ss_arr);
319         }
320
321         /* Test classes as arguments and return values */
322         static int test_0_marshal_class () {
323                 SimpleClass ss = new  SimpleClass ();
324                 ss.b = true;
325                 ss.d = "TEST";
326                 ss.e = 99;
327                 ss.f = 1.5;
328                 ss.g = 42;
329                 ss.h = 123L;
330
331                 SimpleClass res = mono_test_marshal_class (10, 11, 12, ss, 14);
332                 if (res == null)
333                         return 1;
334                 if  (! (res.a == ss.a && res.b == ss.b && res.c == ss.c && 
335                                 res.d == ss.d && res.e == ss.e && res.f == ss.f &&
336                                 res.g == ss.g && res.h == ss.h))
337                         return 2;
338
339                 /* Test null arguments and results */
340                 res = mono_test_marshal_class (10, 11, 12, null, 14);
341                 if (res != null)
342                         return 3;
343
344                 return 0;
345         }
346
347         static int test_0_marshal_byref_class () {
348                 SimpleClass ss = new  SimpleClass ();
349                 ss.b = true;
350                 ss.d = "TEST";
351                 ss.e = 99;
352                 ss.f = 1.5;
353                 ss.g = 42;
354                 ss.h = 123L;
355
356                 int res = mono_test_marshal_byref_class (ref ss);
357                 if (ss.d != "TEST-RES")
358                         return 1;
359
360                 return 0;
361         }
362
363         static int test_0_marshal_delegate () {
364                 SimpleDelegate d = new SimpleDelegate (delegate_test);
365
366                 return mono_test_marshal_delegate (d);
367         }
368
369         static int test_0_marshal_delegate_struct () {
370                 DelegateStruct s = new DelegateStruct ();
371
372                 s.a = 2;
373                 s.del = new SimpleDelegate (delegate_test);
374                 s.del2 = new SimpleDelegate (delegate_test);
375
376                 return mono_test_marshal_delegate_struct (s);
377         }
378
379         static int test_0_marshal_point () {
380                 Point pt = new Point();
381                 pt.x = 1.25;
382                 pt.y = 3.5;
383                 
384                 return mono_test_marshal_point(pt);
385         }
386
387         static int test_0_marshal_mixed_point () {
388                 MixedPoint mpt = new MixedPoint();
389                 mpt.x = 5;
390                 mpt.y = 6.75;
391                 
392                 return mono_test_marshal_mixed_point(mpt);
393         }
394
395         static int test_0_marshal_bool_byref () {
396                 bool b = true;
397                 if (mono_test_marshal_bool_byref (99, ref b, 100) != 1)
398                         return 1;
399                 b = false;
400                 if (mono_test_marshal_bool_byref (99, ref b, 100) != 0)
401                         return 12;
402                 if (b != true)
403                         return 13;
404
405                 return 0;
406         }
407
408         static int test_0_return_vtype () {
409                 SimpleStruct ss = mono_test_return_vtype (new IntPtr (5));
410
411                 if (!ss.a && ss.b && !ss.c && ss.d == "TEST")
412                         return 0;
413                 
414                 return 1;
415         }
416
417         static int test_0_marshal_stringbuilder () {
418                 StringBuilder sb = new StringBuilder(255);
419                 sb.Append ("ABCD");
420                 mono_test_marshal_stringbuilder (sb, sb.Capacity);
421                 String res = sb.ToString();
422
423                 if (res != "This is my message.  Isn't it nice?")
424                         return 1;  
425                 
426                 return 0;
427         }
428
429         static int test_0_marshal_stringbuilder_unicode () {
430                 StringBuilder sb = new StringBuilder(255);
431                 mono_test_marshal_stringbuilder_unicode (sb, sb.Capacity);
432                 String res = sb.ToString();
433
434                 if (res != "This is my message.  Isn't it nice?")
435                         return 1;  
436                 
437                 return 0;
438         }
439
440         static int test_0_marshal_empty_string_array () {
441                 return mono_test_marshal_empty_string_array (null);
442         }
443
444         static int test_0_marshal_string_array () {
445                 return mono_test_marshal_string_array (new String [] { "ABC", "DEF" });
446         }
447
448         static int test_0_marshal_unicode_string_array () {
449                 return mono_test_marshal_unicode_string_array (new String [] { "ABC", "DEF" }, new String [] { "ABC", "DEF" });
450         }
451
452         static int test_0_marshal_stringbuilder_array () {
453                 StringBuilder sb1 = new StringBuilder ("ABC");
454                 StringBuilder sb2 = new StringBuilder ("DEF");
455
456                 int res = mono_test_marshal_stringbuilder_array (new StringBuilder [] { sb1, sb2 });
457                 if (res != 0)
458                         return res;
459                 if (sb1.ToString () != "DEF")
460                         return 5;
461                 if (sb2.ToString () != "ABC")
462                         return 6;
463                 return 0;
464         }
465
466         static int test_0_last_error () {
467                 mono_test_last_error (5);
468                 if (Marshal.GetLastWin32Error () == 5)
469                         return 0;
470                 else
471                         return 1;
472         }
473
474         static int test_0_library_not_found () {
475
476                 try {
477                         mono_entry_point_not_found ();
478                         return 1;
479                 }
480                 catch (EntryPointNotFoundException) {
481                 }
482
483                 return 0;
484         }
485
486         static int test_0_entry_point_not_found () {
487
488                 try {
489                         mono_library_not_found ();
490                         return 1;
491                 }
492                 catch (DllNotFoundException) {
493                 }
494
495                 return 0;
496         }
497
498         /* Check that the runtime trims .dll from the library name */
499         static int test_0_trim_dll_from_name () {
500
501                 mono_test_marshal_char_2 ('A');
502
503                 return 0;
504         }
505
506         class C {
507                 public int i;
508         }
509
510         static int test_0_asany () {
511                 if (mono_test_asany (5, 1) != 0)
512                         return 1;
513
514                 if (mono_test_asany ("ABC", 2) != 0)
515                         return 2;
516
517                 SimpleStruct2 ss2 = new  SimpleStruct2 ();
518                 ss2.b = true;
519                 ss2.d = "TEST";
520                 ss2.e = 99;
521                 ss2.f = 1.5;
522                 ss2.g = 42;
523                 ss2.h = 123L;
524
525                 if (mono_test_asany (ss2, 3) != 0)
526                         return 3;
527
528                 if (mono_test_asany_unicode ("ABC", 4) != 0)
529                         return 4;
530
531                 try {
532                         C c = new C ();
533                         c.i = 5;
534                         mono_test_asany (c, 0);
535                         return 5;
536                 }
537                 catch (ArgumentException) {
538                 }
539
540                 try {
541                         mono_test_asany (new Object (), 0);
542                         return 6;
543                 }
544                 catch (ArgumentException) {
545                 }
546
547                 return 0;
548         }
549 }