2009-09-08 Jonathan Chambers <joncham@gmail.com>
[mono.git] / mono / tests / libtest.c
1 #include <config.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <glib.h>
6 #include <gmodule.h>
7 #include <errno.h>
8 #include <time.h>
9 #include <math.h>
10
11 #ifdef WIN32
12 #include <windows.h>
13 #include "initguid.h"
14 #endif
15
16 #ifdef WIN32
17 #define STDCALL __stdcall
18 #else
19 #define STDCALL
20 #endif
21
22 #ifdef __GNUC__
23 #pragma GCC diagnostic ignored "-Wmissing-prototypes"
24 #endif
25
26 #ifdef WIN32
27 extern __declspec(dllimport) void __stdcall CoTaskMemFree(void *ptr);
28 #endif
29
30 typedef int (STDCALL *SimpleDelegate) (int a);
31
32 #if defined(WIN32) && defined (_MSC_VER)
33 #define LIBTEST_API __declspec(dllexport)
34 #else 
35 #define LIBTEST_API
36 #endif
37
38 static void marshal_free (void *ptr)
39 {
40 #ifdef WIN32
41         CoTaskMemFree (ptr);
42 #else
43         g_free (ptr);
44 #endif
45 }
46
47 static void* marshal_alloc (gsize size)
48 {
49 #ifdef WIN32
50         return CoTaskMemAlloc (size);
51 #else
52         return g_malloc (size);
53 #endif
54 }
55
56
57 static gunichar2* marshal_bstr_alloc(const gchar* str)
58 {
59 #ifdef WIN32
60         gunichar2* ret = NULL;
61         gunichar2* temp = NULL;
62         temp = g_utf8_to_utf16 (str, -1, NULL, NULL, NULL);
63         ret = SysAllocString (temp);
64         g_free (temp);
65         return ret;
66 #else
67         gchar* ret = NULL;
68         int slen = strlen (str);
69         gunichar2* temp;
70         /* allocate len + 1 utf16 characters plus 4 byte integer for length*/
71         ret = g_malloc ((slen + 1) * sizeof(gunichar2) + sizeof(guint32));
72         if (ret == NULL)
73                 return NULL;
74         temp = g_utf8_to_utf16 (str, -1, NULL, NULL, NULL);
75         memcpy (ret + sizeof(guint32), temp, slen * sizeof(gunichar2));
76         * ((guint32 *) ret) = slen * sizeof(gunichar2);
77         ret [4 + slen * sizeof(gunichar2)] = 0;
78         ret [5 + slen * sizeof(gunichar2)] = 0;
79
80         return (gunichar2*)(ret + 4);
81 #endif
82 }
83
84 LIBTEST_API int STDCALL
85 mono_cominterop_is_supported ()
86 {
87 #if defined(TARGET_X86) || defined(TARGET_AMD64)
88         return 1;
89 #endif
90         return 0;
91 }
92
93 LIBTEST_API unsigned short* STDCALL
94 test_lpwstr_marshal (unsigned short* chars, long length)
95 {
96         int i = 0;
97         unsigned short *res;
98
99         res = marshal_alloc (2 * (length + 1));
100
101         // printf("test_lpwstr_marshal()\n");
102         
103         while ( i < length ) {
104                 // printf("X|%u|\n", chars[i]);
105                 res [i] = chars[i];
106                 i++;
107         }
108
109         res [i] = 0;
110
111         return res;
112 }
113
114
115 LIBTEST_API void STDCALL
116 test_lpwstr_marshal_out (unsigned short** chars)
117 {
118         int i = 0;
119         const char abc[] = "ABC";
120         glong len = strlen(abc);
121
122         *chars = marshal_alloc (2 * (len + 1));
123         
124         while ( i < len ) {
125                 (*chars) [i] = abc[i];
126                 i++;
127         }
128
129         (*chars) [i] = 0;
130 }
131
132 typedef struct {
133         int b;
134         int a;
135         int c;
136 } union_test_1_type;
137
138 LIBTEST_API int STDCALL  
139 mono_union_test_1 (union_test_1_type u1) {
140         // printf ("Got values %d %d %d\n", u1.b, u1.a, u1.c);
141         return u1.a + u1.b + u1.c;
142 }
143
144 LIBTEST_API int STDCALL  
145 mono_return_int (int a) {
146         // printf ("Got value %d\n", a);
147         return a;
148 }
149
150 LIBTEST_API float STDCALL  
151 mono_test_marshal_pass_return_float (float f) {
152         return f + 1.0;
153 }
154
155 struct ss
156 {
157         int i;
158 };
159
160 LIBTEST_API int STDCALL 
161 mono_return_int_ss (struct ss a) {
162         // printf ("Got value %d\n", a.i);
163         return a.i;
164 }
165
166 LIBTEST_API struct ss STDCALL
167 mono_return_ss (struct ss a) {
168         // printf ("Got value %d\n", a.i);
169         a.i++;
170         return a;
171 }
172
173 struct sc1
174 {
175         char c[1];
176 };
177
178 LIBTEST_API struct sc1 STDCALL
179 mono_return_sc1 (struct sc1 a) {
180         // printf ("Got value %d\n", a.c[0]);
181         a.c[0]++;
182         return a;
183 }
184
185
186 struct sc3
187 {
188         char c[3];
189 };
190
191 LIBTEST_API struct sc3 STDCALL 
192 mono_return_sc3 (struct sc3 a) {
193         // printf ("Got values %d %d %d\n", a.c[0], a.c[1], a.c[2]);
194         a.c[0]++;
195         a.c[1] += 2;
196         a.c[2] += 3;
197         return a;
198 }
199
200 struct sc5
201 {
202         char c[5];
203 };
204
205 LIBTEST_API struct sc5 STDCALL 
206 mono_return_sc5 (struct sc5 a) {
207         // printf ("Got values %d %d %d %d %d\n", a.c[0], a.c[1], a.c[2], a.c[3], a.c[4]);
208         a.c[0]++;
209         a.c[1] += 2;
210         a.c[2] += 3;
211         a.c[3] += 4;
212         a.c[4] += 5;
213         return a;
214 }
215
216 union su
217 {
218         int i1;
219         int i2;
220 };
221
222 LIBTEST_API int STDCALL  
223 mono_return_int_su (union su a) {
224         // printf ("Got value %d\n", a.i1);
225         return a.i1;
226 }
227
228 LIBTEST_API int STDCALL  
229 mono_test_many_int_arguments (int a, int b, int c, int d, int e,
230                                                           int f, int g, int h, int i, int j);
231 LIBTEST_API short STDCALL 
232 mono_test_many_short_arguments (short a, short b, short c, short d, short e,
233                                                                 short f, short g, short h, short i, short j);
234 LIBTEST_API char STDCALL 
235 mono_test_many_char_arguments (char a, char b, char c, char d, char e,
236                                                            char f, char g, char h, char i, char j);
237
238 LIBTEST_API int STDCALL 
239 mono_test_many_int_arguments (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j)
240 {
241         return a + b + c + d + e + f + g + h + i + j;
242 }
243
244 LIBTEST_API short STDCALL 
245 mono_test_many_short_arguments (short a, short b, short c, short d, short e, short f, short g, short h, short i, short j)
246 {
247         return a + b + c + d + e + f + g + h + i + j;
248 }
249
250 LIBTEST_API char STDCALL 
251 mono_test_many_byte_arguments (char a, char b, char c, char d, char e, char f, char g, char h, char i, char j)
252 {
253         return a + b + c + d + e + f + g + h + i + j;
254 }
255
256 LIBTEST_API float STDCALL 
257 mono_test_many_float_arguments (float a, float b, float c, float d, float e, float f, float g, float h, float i, float j)
258 {
259         return a + b + c + d + e + f + g + h + i + j;
260 }
261
262 LIBTEST_API double STDCALL 
263 mono_test_many_double_arguments (double a, double b, double c, double d, double e, double f, double g, double h, double i, double j)
264 {
265         return a + b + c + d + e + f + g + h + i + j;
266 }
267
268 LIBTEST_API double STDCALL 
269 mono_test_split_double_arguments (double a, double b, float c, double d, double e)
270 {
271         return a + b + c + d + e;
272 }
273
274 LIBTEST_API int STDCALL 
275 mono_test_puts_static (char *s)
276 {
277         // printf ("TEST %s\n", s);
278         return 1;
279 }
280
281 typedef int (STDCALL *SimpleDelegate3) (int a, int b);
282
283 LIBTEST_API int STDCALL 
284 mono_invoke_delegate (SimpleDelegate3 delegate)
285 {
286         int res;
287
288         // printf ("start invoke %p\n", delegate);
289
290         res = delegate (2, 3);
291
292         // printf ("end invoke\n");
293
294         return res;
295 }
296
297 LIBTEST_API int STDCALL
298 mono_invoke_simple_delegate (SimpleDelegate d)
299 {
300         return d (4);
301 }
302
303 LIBTEST_API int STDCALL  
304 mono_test_marshal_char (short a1)
305 {
306         if (a1 == 'a')
307                 return 0;
308         
309         return 1;
310 }
311
312 LIBTEST_API void STDCALL
313 mono_test_marshal_char_array (gunichar2 *s)
314 {
315         const char m[] = "abcdef";
316         gunichar2* s2;
317         glong len;
318
319         s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
320         
321         len = (len * 2) + 2;
322         memcpy (s, s2, len);
323
324         g_free (s2);
325 }
326
327 LIBTEST_API int STDCALL 
328 mono_test_empty_pinvoke (int i)
329 {
330         return i;
331 }
332
333 LIBTEST_API int STDCALL  
334 mono_test_marshal_bool_byref (int a, int *b, int c)
335 {
336     int res = *b;
337
338         *b = 1;
339
340         return res;
341 }
342
343 LIBTEST_API int STDCALL 
344 mono_test_marshal_bool_in_as_I1_U1 (char bTrue, char bFalse)
345 {
346         if (!bTrue)
347                 return 1;
348         if (bFalse)
349                 return 2;
350         return 0;
351 }
352
353 LIBTEST_API int STDCALL 
354 mono_test_marshal_bool_out_as_I1_U1 (char* bTrue, char* bFalse)
355 {
356         if (!bTrue || !bFalse)
357                 return 3;
358
359         *bTrue = 1;
360         *bFalse = 0;
361
362         return 0;
363 }
364
365 LIBTEST_API int STDCALL 
366 mono_test_marshal_bool_ref_as_I1_U1 (char* bTrue, char* bFalse)
367 {
368         if (!bTrue || !bFalse)
369                 return 4;
370
371         if (!(*bTrue))
372                 return 5;
373         if (*bFalse)
374                 return 6;
375
376         *bFalse = 1;
377         *bTrue = 0;
378
379         return 0;
380 }
381
382 LIBTEST_API int STDCALL  
383 mono_test_marshal_array (int *a1)
384 {
385         int i, sum = 0;
386
387         for (i = 0; i < 50; i++)
388                 sum += a1 [i];
389         
390         return sum;
391 }
392
393 LIBTEST_API int STDCALL  
394 mono_test_marshal_inout_array (int *a1)
395 {
396         int i, sum = 0;
397
398         for (i = 0; i < 50; i++) {
399                 sum += a1 [i];
400                 a1 [i] = 50 - a1 [i];
401         }
402         
403         return sum;
404 }
405
406 LIBTEST_API int STDCALL  
407 mono_test_marshal_out_array (int *a1)
408 {
409         int i;
410
411         for (i = 0; i < 50; i++) {
412                 a1 [i] = i;
413         }
414         
415         return 0;
416 }
417
418 LIBTEST_API int STDCALL  
419 mono_test_marshal_inout_nonblittable_array (gunichar2 *a1)
420 {
421         int i, sum = 0;
422
423         for (i = 0; i < 10; i++) {
424                 a1 [i] = 'F';
425         }
426         
427         return sum;
428 }
429
430 typedef struct {
431         int a;
432         int b;
433         int c;
434         const char *d;
435         gunichar2 *d2;
436 } simplestruct;
437
438 typedef struct {
439         double x;
440         double y;
441 } point;
442
443 LIBTEST_API simplestruct STDCALL 
444 mono_test_return_vtype (int i)
445 {
446         simplestruct res;
447         static gunichar2 test2 [] = { 'T', 'E', 'S', 'T', '2', 0 };
448
449         res.a = 0;
450         res.b = 1;
451         res.c = 0;
452         res.d = "TEST";
453         res.d2 = test2;
454
455         return res;
456 }
457
458 LIBTEST_API void STDCALL
459 mono_test_delegate_struct (void)
460 {
461         // printf ("TEST\n");
462 }
463
464 typedef char* (STDCALL *ReturnStringDelegate) (const char *s);
465
466 LIBTEST_API char * STDCALL 
467 mono_test_return_string (ReturnStringDelegate func)
468 {
469         char *res;
470
471         // printf ("mono_test_return_string\n");
472
473         res = func ("TEST");
474         marshal_free (res);
475
476         // printf ("got string: %s\n", res);
477         return g_strdup ("12345");
478 }
479
480 typedef int (STDCALL *RefVTypeDelegate) (int a, simplestruct *ss, int b);
481
482 LIBTEST_API int STDCALL 
483 mono_test_ref_vtype (int a, simplestruct *ss, int b, RefVTypeDelegate func)
484 {
485         if (a == 1 && b == 2 && ss->a == 0 && ss->b == 1 && ss->c == 0 &&
486             !strcmp (ss->d, "TEST1")) {
487                 ss->a = 1;
488                 ss->b = 0;
489                 ss->c = 1;
490                 ss->d = "TEST2";
491
492                 return func (a, ss, b);
493         }
494
495         return 1;
496 }
497
498 typedef int (STDCALL *OutVTypeDelegate) (int a, simplestruct *ss, int b);
499
500 LIBTEST_API int STDCALL 
501 mono_test_marshal_out_struct (int a, simplestruct *ss, int b, OutVTypeDelegate func)
502 {
503         /* Check that the input pointer is ignored */
504         ss->d = (gpointer)0x12345678;
505
506         func (a, ss, b);
507
508         if (ss->a && ss->b && ss->c && !strcmp (ss->d, "TEST3"))
509                 return 0;
510         else
511                 return 1;
512 }
513
514 typedef struct {
515         int a;
516         SimpleDelegate func, func2, func3;
517 } DelegateStruct;
518
519 LIBTEST_API DelegateStruct STDCALL 
520 mono_test_marshal_delegate_struct (DelegateStruct ds)
521 {
522         DelegateStruct res;
523
524         res.a = ds.func (ds.a) + ds.func2 (ds.a) + (ds.func3 == NULL ? 0 : 1);
525         res.func = ds.func;
526         res.func2 = ds.func2;
527         res.func3 = NULL;
528
529         return res;
530 }
531
532 LIBTEST_API int STDCALL  
533 mono_test_marshal_struct (simplestruct ss)
534 {
535         if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
536             !strcmp (ss.d, "TEST"))
537                 return 0;
538
539         return 1;
540 }
541
542 LIBTEST_API int STDCALL 
543 mono_test_marshal_byref_struct (simplestruct *ss, int a, int b, int c, char *d)
544 {
545         gboolean res = (ss->a == a && ss->b == b && ss->c == c && strcmp (ss->d, d) == 0);
546
547         marshal_free ((char*)ss->d);
548
549         ss->a = !ss->a;
550         ss->b = !ss->b;
551         ss->c = !ss->c;
552         ss->d = g_strdup ("DEF");
553
554         return res ? 0 : 1;
555 }
556
557 typedef struct {
558         int a;
559         int b;
560         int c;
561         char *d;
562         unsigned char e;
563         double f;
564         unsigned char g;
565         guint64 h;
566 } simplestruct2;
567
568 LIBTEST_API int STDCALL 
569 mono_test_marshal_struct2 (simplestruct2 ss)
570 {
571         if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
572             !strcmp (ss.d, "TEST") && 
573             ss.e == 99 && ss.f == 1.5 && ss.g == 42 && ss.h == (guint64)123)
574                 return 0;
575
576         return 1;
577 }
578
579 /* on HP some of the struct should be on the stack and not in registers */
580 LIBTEST_API int STDCALL 
581 mono_test_marshal_struct2_2 (int i, int j, int k, simplestruct2 ss)
582 {
583         if (i != 10 || j != 11 || k != 12)
584                 return 1;
585         if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
586             !strcmp (ss.d, "TEST") && 
587             ss.e == 99 && ss.f == 1.5 && ss.g == 42 && ss.h == (guint64)123)
588                 return 0;
589
590         return 1;
591 }
592
593 LIBTEST_API int STDCALL  
594 mono_test_marshal_lpstruct (simplestruct *ss)
595 {
596         if (ss->a == 0 && ss->b == 1 && ss->c == 0 &&
597             !strcmp (ss->d, "TEST"))
598                 return 0;
599
600         return 1;
601 }
602
603 LIBTEST_API int STDCALL  
604 mono_test_marshal_lpstruct_blittable (point *p)
605 {
606         if (p->x == 1.0 && p->y == 2.0)
607                 return 0;
608         else
609                 return 1;
610 }
611
612 LIBTEST_API int STDCALL 
613 mono_test_marshal_struct_array (simplestruct2 *ss)
614 {
615         if (! (ss[0].a == 0 && ss[0].b == 1 && ss[0].c == 0 &&
616                    !strcmp (ss[0].d, "TEST") && 
617                    ss[0].e == 99 && ss[0].f == 1.5 && ss[0].g == 42 && ss[0].h == (guint64)123))
618                 return 1;
619
620         if (! (ss[1].a == 0 && ss[1].b == 0 && ss[1].c == 0 &&
621                    !strcmp (ss[1].d, "TEST2") && 
622                    ss[1].e == 100 && ss[1].f == 2.5 && ss[1].g == 43 && ss[1].h == (guint64)124))
623                 return 1;
624
625         return 0;
626 }
627
628 typedef struct long_align_struct {
629         gint32 a;
630         gint64 b;
631         gint64 c;
632 } long_align_struct;
633
634 LIBTEST_API int STDCALL 
635 mono_test_marshal_long_align_struct_array (long_align_struct *ss)
636 {
637         return ss[0].a + ss[0].b + ss[0].c + ss[1].a + ss[1].b + ss[1].c;
638 }
639
640 LIBTEST_API simplestruct2 * STDCALL 
641 mono_test_marshal_class (int i, int j, int k, simplestruct2 *ss, int l)
642 {
643         simplestruct2 *res;
644
645         if (!ss)
646                 return NULL;
647
648         if (i != 10 || j != 11 || k != 12 || l != 14)
649                 return NULL;
650         if (! (ss->a == 0 && ss->b == 1 && ss->c == 0 &&
651                    !strcmp (ss->d, "TEST") && 
652                    ss->e == 99 && ss->f == 1.5 && ss->g == 42 && ss->h == (guint64)123))
653                 return NULL;
654
655         res = g_new0 (simplestruct2, 1);
656         memcpy (res, ss, sizeof (simplestruct2));
657         res->d = g_strdup ("TEST");
658         return res;
659 }
660
661 LIBTEST_API int STDCALL 
662 mono_test_marshal_byref_class (simplestruct2 **ssp)
663 {
664         simplestruct2 *ss = *ssp;
665         simplestruct2 *res;
666         
667         if (! (ss->a == 0 && ss->b == 1 && ss->c == 0 &&
668                    !strcmp (ss->d, "TEST") && 
669                    ss->e == 99 && ss->f == 1.5 && ss->g == 42 && ss->h == (guint64)123))
670                 return 1;
671
672         res = g_new0 (simplestruct2, 1);
673         memcpy (res, ss, sizeof (simplestruct2));
674         res->d = g_strdup ("TEST-RES");
675
676         *ssp = res;
677         return 0;
678 }
679
680 static void *
681 get_sp (void)
682 {
683         int i;
684         void *p;
685
686         /* Yes, this is correct, we are only trying to determine the value of the stack here */
687         p = &i;
688         return p;
689 }
690
691 LIBTEST_API int STDCALL 
692 reliable_delegate (int a)
693 {
694         return a;
695 }
696
697 /*
698  * Checks whether get_sp() works as expected. It doesn't work with gcc-2.95.3 on linux.
699  */
700 static gboolean
701 is_get_sp_reliable (void)
702 {
703         void *sp1, *sp2;
704
705         reliable_delegate(1);
706         sp1 = get_sp();
707         reliable_delegate(1);
708         sp2 = get_sp();
709         return sp1 == sp2;
710
711
712 LIBTEST_API int STDCALL 
713 mono_test_marshal_delegate (SimpleDelegate delegate)
714 {
715         void *sp1, *sp2;
716
717         /* Check that the delegate wrapper is stdcall */
718         delegate (2);
719         sp1 = get_sp ();
720         delegate (2);
721         sp2 = get_sp ();
722         if (is_get_sp_reliable())
723                 g_assert (sp1 == sp2);
724
725         return delegate (2);
726 }
727
728 static int STDCALL inc_cb (int i)
729 {
730         return i + 1;
731 }
732
733 LIBTEST_API int STDCALL 
734 mono_test_marshal_out_delegate (SimpleDelegate *delegate)
735 {
736         *delegate = inc_cb;
737
738         return 0;
739 }
740
741 LIBTEST_API SimpleDelegate STDCALL 
742 mono_test_marshal_return_delegate (SimpleDelegate delegate)
743 {
744         return delegate;
745 }
746
747 static int STDCALL
748 return_plus_one (int i)
749 {
750         return i + 1;
751 }
752
753 LIBTEST_API SimpleDelegate STDCALL 
754 mono_test_marshal_return_delegate_2 (void)
755 {
756         return return_plus_one;
757 }
758
759 typedef simplestruct (STDCALL *SimpleDelegate2) (simplestruct ss);
760
761 static gboolean
762 is_utf16_equals (gunichar2 *s1, const char *s2)
763 {
764         char *s;
765         int res;
766
767         s = g_utf16_to_utf8 (s1, -1, NULL, NULL, NULL);
768         res = strcmp (s, s2);
769         g_free (s);
770
771         return res == 0;
772 }
773
774 LIBTEST_API int STDCALL 
775 mono_test_marshal_delegate2 (SimpleDelegate2 delegate)
776 {
777         simplestruct ss, res;
778
779         ss.a = 0;
780         ss.b = 1;
781         ss.c = 0;
782         ss.d = "TEST";
783         ss.d2 = g_utf8_to_utf16 ("TEST2", -1, NULL, NULL, NULL); 
784
785         res = delegate (ss);
786         if (! (res.a && !res.b && res.c && !strcmp (res.d, "TEST-RES") && is_utf16_equals (res.d2, "TEST2-RES")))
787                 return 1;
788
789         return 0;
790 }
791
792 typedef simplestruct* (STDCALL *SimpleDelegate4) (simplestruct *ss);
793
794 LIBTEST_API int STDCALL 
795 mono_test_marshal_delegate4 (SimpleDelegate4 delegate)
796 {
797         simplestruct ss;
798         simplestruct *res;
799
800         ss.a = 0;
801         ss.b = 1;
802         ss.c = 0;
803         ss.d = "TEST";
804
805         /* Check argument */
806         res = delegate (&ss);
807         if (!res)
808                 return 1;
809
810         /* Check return value */
811         if (! (!res->a && res->b && !res->c && !strcmp (res->d, "TEST")))
812                 return 2;
813
814         /* Check NULL argument and NULL result */
815         res = delegate (NULL);
816         if (res)
817                 return 3;
818
819         return 0;
820 }
821
822 typedef int (STDCALL *SimpleDelegate5) (simplestruct **ss);
823
824 LIBTEST_API int STDCALL 
825 mono_test_marshal_delegate5 (SimpleDelegate5 delegate)
826 {
827         simplestruct ss;
828         int res;
829         simplestruct *ptr;
830
831         ss.a = 0;
832         ss.b = 1;
833         ss.c = 0;
834         ss.d = "TEST";
835
836         ptr = &ss;
837
838         res = delegate (&ptr);
839         if (res != 0)
840                 return 1;
841
842         if (!(ptr->a && !ptr->b && ptr->c && !strcmp (ptr->d, "RES")))
843                 return 2;
844
845         return 0;
846 }
847
848 LIBTEST_API int STDCALL 
849 mono_test_marshal_delegate6 (SimpleDelegate5 delegate)
850 {
851         int res;
852
853         res = delegate (NULL);
854
855         return 0;
856 }
857
858 typedef int (STDCALL *SimpleDelegate7) (simplestruct **ss);
859
860 LIBTEST_API int STDCALL 
861 mono_test_marshal_delegate7 (SimpleDelegate7 delegate)
862 {
863         int res;
864         simplestruct *ptr;
865
866         /* Check that the input pointer is ignored */
867         ptr = (gpointer)0x12345678;
868
869         res = delegate (&ptr);
870         if (res != 0)
871                 return 1;
872
873         if (!(ptr->a && !ptr->b && ptr->c && !strcmp (ptr->d, "RES")))
874                 return 2;
875
876         return 0;
877 }
878
879 typedef int (STDCALL *InOutByvalClassDelegate) (simplestruct *ss);
880
881 LIBTEST_API int STDCALL 
882 mono_test_marshal_inout_byval_class_delegate (InOutByvalClassDelegate delegate)
883 {
884         int res;
885         simplestruct ss;
886
887         ss.a = FALSE;
888         ss.b = TRUE;
889         ss.c = FALSE;
890         ss.d = g_strdup_printf ("%s", "FOO");
891
892         res = delegate (&ss);
893         if (res != 0)
894                 return 1;
895
896         if (!(ss.a && !ss.b && ss.c && !strcmp (ss.d, "RES")))
897                 return 2;
898
899         return 0;
900 }
901
902 typedef int (STDCALL *SimpleDelegate8) (gunichar2 *s);
903
904 LIBTEST_API int STDCALL 
905 mono_test_marshal_delegate8 (SimpleDelegate8 delegate, gunichar2 *s)
906 {
907         return delegate (s);
908 }
909
910 typedef int (STDCALL *return_int_fnt) (int i);
911 typedef int (STDCALL *SimpleDelegate9) (return_int_fnt d);
912
913 LIBTEST_API int STDCALL 
914 mono_test_marshal_delegate9 (SimpleDelegate9 delegate, gpointer ftn)
915 {
916         return delegate (ftn);
917 }
918
919 static int STDCALL 
920 return_self (int i)
921 {
922         return i;
923 }
924
925 LIBTEST_API int STDCALL 
926 mono_test_marshal_delegate10 (SimpleDelegate9 delegate)
927 {
928         return delegate (return_self);
929 }
930
931 typedef int (STDCALL *PrimitiveByrefDelegate) (int *i);
932
933 LIBTEST_API int STDCALL 
934 mono_test_marshal_primitive_byref_delegate (PrimitiveByrefDelegate delegate)
935 {
936         int i = 1;
937
938         int res = delegate (&i);
939         if (res != 0)
940                 return res;
941
942         if (i != 2)
943                 return 2;
944
945         return 0;
946 }
947
948 typedef int (STDCALL *return_int_delegate) (int i);
949
950 typedef return_int_delegate (STDCALL *ReturnDelegateDelegate) (void);
951
952 LIBTEST_API int STDCALL 
953 mono_test_marshal_return_delegate_delegate (ReturnDelegateDelegate d)
954 {
955         return (d ()) (55);
956 }
957
958 LIBTEST_API int STDCALL  
959 mono_test_marshal_stringbuilder (char *s, int n)
960 {
961         const char m[] = "This is my message.  Isn't it nice?";
962
963         if (strcmp (s, "ABCD") != 0)
964                 return 1;
965         strncpy(s, m, n);
966         s [n] = '\0';
967         return 0;
968 }
969
970 LIBTEST_API int STDCALL  
971 mono_test_marshal_stringbuilder_default (char *s, int n)
972 {
973         const char m[] = "This is my message.  Isn't it nice?";
974
975         strncpy(s, m, n);
976         s [n] = '\0';
977         return 0;
978 }
979
980 LIBTEST_API int STDCALL  
981 mono_test_marshal_stringbuilder_unicode (gunichar2 *s, int n)
982 {
983         const char m[] = "This is my message.  Isn't it nice?";
984         gunichar2* s2;
985         glong len;
986
987         s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
988         
989         len = (len * 2) + 2;
990         if (len > (n * 2))
991                 len = n * 2;
992         memcpy (s, s2, len);
993
994         g_free (s2);
995
996         return 0;
997 }
998
999 typedef struct {
1000 #ifndef __GNUC__
1001     char a;
1002 #endif
1003 } EmptyStruct;
1004
1005 LIBTEST_API int STDCALL 
1006 mono_test_marshal_empty_string_array (char **array)
1007 {
1008         return (array == NULL) ? 0 : 1;
1009 }
1010
1011 LIBTEST_API int STDCALL 
1012 mono_test_marshal_string_array (char **array)
1013 {
1014         if (strcmp (array [0], "ABC"))
1015                 return 1;
1016         if (strcmp (array [1], "DEF"))
1017                 return 2;
1018
1019         if (array [2] != NULL)
1020                 return 3;
1021
1022         return 0;
1023 }
1024
1025 LIBTEST_API int STDCALL 
1026 mono_test_marshal_byref_string_array (char ***array)
1027 {
1028         if (*array == NULL)
1029                 return 0;
1030
1031         if (strcmp ((*array) [0], "Alpha"))
1032                 return 2;
1033         if (strcmp ((*array) [1], "Beta"))
1034                 return 2;
1035         if (strcmp ((*array) [2], "Gamma"))
1036                 return 2;
1037
1038         return 1;
1039 }
1040
1041 LIBTEST_API int STDCALL 
1042 mono_test_marshal_stringbuilder_array (char **array)
1043 {
1044         if (strcmp (array [0], "ABC"))
1045                 return 1;
1046         if (strcmp (array [1], "DEF"))
1047                 return 2;
1048
1049         strcpy (array [0], "DEF");
1050         strcpy (array [1], "ABC");
1051
1052         return 0;
1053 }
1054
1055 LIBTEST_API int STDCALL 
1056 mono_test_marshal_unicode_string_array (gunichar2 **array, char **array2)
1057 {
1058         GError *error = NULL;
1059         char *s;
1060         
1061         s = g_utf16_to_utf8 (array [0], -1, NULL, NULL, &error);
1062         if (strcmp (s, "ABC")) {
1063                 g_free (s);
1064                 return 1;
1065         }
1066         else
1067                 g_free (s);
1068
1069         s = g_utf16_to_utf8 (array [1], -1, NULL, NULL, &error);
1070         if (strcmp (s, "DEF")) {
1071                 g_free (s);
1072                 return 2;
1073         }
1074         else
1075                 g_free (s);
1076
1077         if (strcmp (array2 [0], "ABC"))
1078                 return 3;
1079
1080         if (strcmp (array2 [1], "DEF")) 
1081                 return 4;
1082
1083         return 0;
1084 }
1085
1086 /* this does not work on Redhat gcc 2.96 */
1087 LIBTEST_API int STDCALL  
1088 mono_test_empty_struct (int a, EmptyStruct es, int b)
1089 {
1090         // printf ("mono_test_empty_struct %d %d\n", a, b);
1091
1092         // Intel icc on ia64 passes 'es' in 2 registers
1093 #if defined(__ia64) && defined(__INTEL_COMPILER)
1094         return 0;
1095 #else
1096         if (a == 1 && b == 2)
1097                 return 0;
1098         return 1;
1099 #endif
1100 }
1101
1102 typedef struct {
1103        char a[100];
1104 } ByValStrStruct;
1105
1106 LIBTEST_API ByValStrStruct * STDCALL 
1107 mono_test_byvalstr_gen (void)
1108 {
1109         ByValStrStruct *ret;
1110        
1111         ret = malloc(sizeof(ByValStrStruct));
1112         memset(ret, 'a', sizeof(ByValStrStruct)-1);
1113         ret->a[sizeof(ByValStrStruct)-1] = 0;
1114
1115         return ret;
1116 }
1117
1118 LIBTEST_API int STDCALL 
1119 mono_test_byvalstr_check (ByValStrStruct* data, char* correctString)
1120 {
1121         int ret;
1122
1123         ret = strcmp(data->a, correctString);
1124         // printf ("T1: %s\n", data->a);
1125         // printf ("T2: %s\n", correctString);
1126
1127         marshal_free (data);
1128         return (ret != 0);
1129 }
1130
1131 typedef struct {
1132         guint16 a[4];
1133         int  flag;
1134 } ByValStrStruct_Unicode;
1135
1136 LIBTEST_API int STDCALL 
1137 mono_test_byvalstr_check_unicode (ByValStrStruct_Unicode *ref, int test)
1138 {
1139         if (ref->flag != 0x1234abcd){
1140                 printf ("overwritten data");
1141                 return 1;
1142         }
1143             
1144         if (test == 1 || test == 3){
1145                 if (ref->a [0] != '1' ||
1146                     ref->a [1] != '2'   ||
1147                     ref->a [2] != '3')
1148                         return 1;
1149                 return 0;
1150         }
1151         if (test == 2){
1152                 if (ref->a [0] != '1' ||
1153                     ref->a [1] != '2')
1154                         return 1;
1155                 return 0;
1156         }
1157         return 10;
1158 }
1159
1160 LIBTEST_API int STDCALL 
1161 NameManglingAnsi (char *data)
1162 {
1163         return data [0] + data [1] + data [2];
1164 }
1165
1166 LIBTEST_API int STDCALL 
1167 NameManglingAnsiA (char *data)
1168 {
1169         g_assert_not_reached ();
1170 }
1171
1172 LIBTEST_API int STDCALL 
1173 NameManglingAnsiW (char *data)
1174 {
1175         g_assert_not_reached ();
1176 }
1177
1178 LIBTEST_API int STDCALL 
1179 NameManglingAnsi2A (char *data)
1180 {
1181         return data [0] + data [1] + data [2];
1182 }
1183
1184 LIBTEST_API int STDCALL 
1185 NameManglingAnsi2W (char *data)
1186 {
1187         g_assert_not_reached ();
1188 }
1189
1190 LIBTEST_API int STDCALL 
1191 NameManglingUnicode (char *data)
1192 {
1193         g_assert_not_reached ();
1194 }
1195
1196 LIBTEST_API int STDCALL 
1197 NameManglingUnicodeW (gunichar2 *data)
1198 {
1199         return data [0] + data [1] + data [2];
1200 }
1201
1202 LIBTEST_API int STDCALL 
1203 NameManglingUnicode2 (gunichar2 *data)
1204 {
1205         return data [0] + data [1] + data [2];
1206 }
1207
1208 LIBTEST_API int STDCALL 
1209 NameManglingAutoW (char *data)
1210 {
1211 #ifdef WIN32
1212         return (data [0] + data [1] + data [2]) == 131 ? 0 : 1;
1213 #else
1214         g_assert_not_reached ();
1215 #endif
1216 }
1217
1218 LIBTEST_API int STDCALL 
1219 NameManglingAuto (char *data)
1220 {
1221 #ifndef WIN32
1222         return (data [0] + data [1] + data [2]) == 198 ? 0 : 1;
1223 #else
1224         g_assert_not_reached ();
1225 #endif
1226 }
1227
1228 typedef int (STDCALL *intcharFunc)(const char*);
1229
1230 LIBTEST_API void STDCALL 
1231 callFunction (intcharFunc f)
1232 {
1233         f ("ABC");
1234 }
1235
1236 typedef struct {
1237         const char* str;
1238         int i;
1239 } SimpleObj;
1240
1241 LIBTEST_API int STDCALL 
1242 class_marshal_test0 (SimpleObj *obj1)
1243 {
1244         // printf ("class_marshal_test0 %s %d\n", obj1->str, obj1->i);
1245
1246         if (strcmp(obj1->str, "T1"))
1247                 return -1;
1248         if (obj1->i != 4)
1249                 return -2;
1250
1251         return 0;
1252 }
1253
1254 LIBTEST_API int STDCALL 
1255 class_marshal_test4 (SimpleObj *obj1)
1256 {
1257         if (obj1)
1258                 return -1;
1259
1260         return 0;
1261 }
1262
1263 LIBTEST_API void STDCALL
1264 class_marshal_test1 (SimpleObj **obj1)
1265 {
1266         SimpleObj *res = malloc (sizeof (SimpleObj));
1267
1268         res->str = g_strdup ("ABC");
1269         res->i = 5;
1270
1271         *obj1 = res;
1272 }
1273
1274 LIBTEST_API int STDCALL 
1275 class_marshal_test2 (SimpleObj **obj1)
1276 {
1277         // printf ("class_marshal_test2 %s %d\n", (*obj1)->str, (*obj1)->i);
1278
1279         if (strcmp((*obj1)->str, "ABC"))
1280                 return -1;
1281         if ((*obj1)->i != 5)
1282                 return -2;
1283
1284         return 0;
1285 }
1286
1287 LIBTEST_API int STDCALL 
1288 string_marshal_test0 (char *str)
1289 {
1290         if (strcmp (str, "TEST0"))
1291                 return -1;
1292
1293         return 0;
1294 }
1295
1296 LIBTEST_API void STDCALL
1297 string_marshal_test1 (const char **str)
1298 {
1299         *str = g_strdup ("TEST1");
1300 }
1301
1302 LIBTEST_API int STDCALL 
1303 string_marshal_test2 (char **str)
1304 {
1305         // printf ("string_marshal_test2 %s\n", *str);
1306
1307         if (strcmp (*str, "TEST1"))
1308                 return -1;
1309
1310         return 0;
1311 }
1312
1313 LIBTEST_API int STDCALL 
1314 string_marshal_test3 (char *str)
1315 {
1316         if (str)
1317                 return -1;
1318
1319         return 0;
1320 }
1321
1322 typedef struct {
1323         int a;
1324         int b;
1325 } BlittableClass;
1326
1327 LIBTEST_API BlittableClass* STDCALL 
1328 TestBlittableClass (BlittableClass *vl)
1329 {
1330         BlittableClass *res;
1331
1332         // printf ("TestBlittableClass %d %d\n", vl->a, vl->b);
1333
1334         if (vl) {
1335                 vl->a++;
1336                 vl->b++;
1337
1338                 res = g_new0 (BlittableClass, 1);
1339                 memcpy (res, vl, sizeof (BlittableClass));
1340         } else {
1341                 res = g_new0 (BlittableClass, 1);
1342                 res->a = 42;
1343                 res->b = 43;
1344         }
1345
1346         return res;
1347 }
1348
1349 typedef struct OSVERSIONINFO_STRUCT
1350
1351         int a; 
1352         int b; 
1353 } OSVERSIONINFO_STRUCT;
1354
1355 LIBTEST_API int STDCALL  
1356 MyGetVersionEx (OSVERSIONINFO_STRUCT *osvi)
1357 {
1358
1359         // printf ("GOT %d %d\n", osvi->a, osvi->b);
1360
1361         osvi->a += 1;
1362         osvi->b += 1;
1363
1364         return osvi->a + osvi->b;
1365 }
1366
1367 LIBTEST_API int STDCALL  
1368 BugGetVersionEx (int a, int b, int c, int d, int e, int f, int g, int h, OSVERSIONINFO_STRUCT *osvi)
1369 {
1370
1371         // printf ("GOT %d %d\n", osvi->a, osvi->b);
1372
1373         osvi->a += 1;
1374         osvi->b += 1;
1375
1376         return osvi->a + osvi->b;
1377 }
1378
1379 LIBTEST_API int STDCALL 
1380 mono_test_marshal_point (point pt)
1381 {
1382         // printf("point %g %g\n", pt.x, pt.y);
1383         if (pt.x == 1.25 && pt.y == 3.5)
1384                 return 0;
1385
1386         return 1;
1387 }
1388
1389 typedef struct {
1390         int x;
1391         double y;
1392 } mixed_point;
1393
1394 LIBTEST_API int STDCALL 
1395 mono_test_marshal_mixed_point (mixed_point pt)
1396 {
1397         // printf("mixed point %d %g\n", pt.x, pt.y);
1398         if (pt.x == 5 && pt.y == 6.75)
1399                 return 0;
1400
1401         return 1;
1402 }
1403
1404 LIBTEST_API int STDCALL 
1405 mono_test_marshal_mixed_point_2 (mixed_point *pt)
1406 {
1407         if (pt->x != 5 || pt->y != 6.75)
1408                 return 1;
1409
1410         pt->x = 10;
1411         pt->y = 12.35;
1412
1413         return 0;
1414 }
1415
1416 LIBTEST_API int STDCALL  
1417 marshal_test_ref_bool(int i, char *b1, short *b2, int *b3)
1418 {
1419     int res = 1;
1420     if (*b1 != 0 && *b1 != 1)
1421         return 1;
1422     if (*b2 != 0 && *b2 != -1) /* variant_bool */
1423         return 1;
1424     if (*b3 != 0 && *b3 != 1)
1425         return 1;
1426     if (i == ((*b1 << 2) | (-*b2 << 1) | *b3))
1427         res = 0;
1428     *b1 = !*b1;
1429     *b2 = ~*b2;
1430     *b3 = !*b3;
1431     return res;
1432 }
1433
1434 struct BoolStruct
1435 {
1436     int i;
1437     char b1;
1438     short b2; /* variant_bool */
1439     int b3;
1440 };
1441
1442 LIBTEST_API int STDCALL  
1443 marshal_test_bool_struct(struct BoolStruct *s)
1444 {
1445     int res = 1;
1446     if (s->b1 != 0 && s->b1 != 1)
1447         return 1;
1448     if (s->b2 != 0 && s->b2 != -1)
1449         return 1;
1450     if (s->b3 != 0 && s->b3 != 1)
1451         return 1;
1452     if (s->i == ((s->b1 << 2) | (-s->b2 << 1) | s->b3))
1453         res = 0;
1454     s->b1 = !s->b1;
1455     s->b2 = ~s->b2;
1456     s->b3 = !s->b3;
1457     return res;
1458 }
1459
1460 typedef struct {
1461         gint64 l;
1462 } LongStruct2;
1463
1464 typedef struct {
1465         int i;
1466         LongStruct2 l;
1467 } LongStruct;
1468
1469 LIBTEST_API int STDCALL
1470 mono_test_marshal_long_struct (LongStruct *s)
1471 {
1472         return s->i + s->l.l;
1473 }
1474
1475 LIBTEST_API void STDCALL
1476 mono_test_last_error (int err)
1477 {
1478 #ifdef WIN32
1479         SetLastError (err);
1480 #else
1481         errno = err;
1482 #endif
1483 }
1484
1485 LIBTEST_API int STDCALL 
1486 mono_test_asany (void *ptr, int what)
1487 {
1488         switch (what) {
1489         case 1:
1490                 return (*(int*)ptr == 5) ? 0 : 1;
1491         case 2:
1492                 return strcmp (ptr, "ABC") == 0 ? 0 : 1;
1493         case 3: {
1494                 simplestruct2 ss = *(simplestruct2*)ptr;
1495
1496                 if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
1497             !strcmp (ss.d, "TEST") && 
1498             ss.e == 99 && ss.f == 1.5 && ss.g == 42 && ss.h == (guint64)123)
1499                         return 0;
1500                 else
1501                         return 1;
1502         }
1503         case 4: {
1504                 GError *error = NULL;
1505                 char *s;
1506
1507                 s = g_utf16_to_utf8 (ptr, -1, NULL, NULL, &error);
1508                 if (!strcmp (s, "ABC")) {
1509                         g_free (s);
1510                         return 0;
1511                 }
1512                 else {
1513                         g_free (s);
1514                         return 1;
1515                 }
1516         }
1517         default:
1518                 g_assert_not_reached ();
1519         }
1520
1521         return 1;
1522 }
1523
1524 typedef struct
1525 {
1526         int i;
1527         int j;
1528         int k;
1529         char *s;
1530 } AsAnyStruct;
1531
1532 LIBTEST_API int STDCALL 
1533 mono_test_marshal_asany_in (void* ptr)
1534 {
1535         AsAnyStruct* asAny = ptr;
1536         int res = asAny->i + asAny->j + asAny->k;
1537
1538         return res;
1539 }
1540
1541 LIBTEST_API int STDCALL 
1542 mono_test_marshal_asany_inout (void* ptr)
1543 {
1544         AsAnyStruct* asAny = ptr;
1545         int res = asAny->i + asAny->j + asAny->k;
1546
1547         marshal_free (asAny->s);
1548
1549         asAny->i = 10;
1550         asAny->j = 20;
1551         asAny->k = 30;
1552         asAny->s = 0;
1553
1554         return res;
1555 }
1556
1557 LIBTEST_API int STDCALL 
1558 mono_test_marshal_asany_out (void* ptr)
1559 {
1560         AsAnyStruct* asAny = ptr;
1561         int res = asAny->i + asAny->j + asAny->k;
1562
1563         asAny->i = 10;
1564         asAny->j = 20;
1565         asAny->k = 30;
1566         asAny->s = 0;
1567
1568         return res;
1569 }
1570
1571 /*
1572  * AMD64 marshalling tests.
1573  */
1574
1575 typedef struct amd64_struct1 {
1576         int i;
1577         int j;
1578         int k;
1579         int l;
1580 } amd64_struct1;
1581
1582 LIBTEST_API amd64_struct1 STDCALL 
1583 mono_test_marshal_amd64_pass_return_struct1 (amd64_struct1 s)
1584 {
1585         s.i ++;
1586         s.j ++;
1587         s.k ++;
1588         s.l ++;
1589
1590         return s;
1591 }
1592
1593 LIBTEST_API amd64_struct1 STDCALL 
1594 mono_test_marshal_amd64_pass_return_struct1_many_args (amd64_struct1 s, int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8)
1595 {
1596         s.i ++;
1597         s.j ++;
1598         s.k ++;
1599         s.l += 1 + i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8;
1600
1601         return s;
1602 }
1603
1604 typedef struct amd64_struct2 {
1605         int i;
1606         int j;
1607 } amd64_struct2;
1608
1609 LIBTEST_API amd64_struct2 STDCALL 
1610 mono_test_marshal_amd64_pass_return_struct2 (amd64_struct2 s)
1611 {
1612         s.i ++;
1613         s.j ++;
1614
1615         return s;
1616 }
1617
1618 typedef struct amd64_struct3 {
1619         int i;
1620 } amd64_struct3;
1621
1622 LIBTEST_API amd64_struct3 STDCALL 
1623 mono_test_marshal_amd64_pass_return_struct3 (amd64_struct3 s)
1624 {
1625         s.i ++;
1626
1627         return s;
1628 }
1629
1630 typedef struct amd64_struct4 {
1631         double d1, d2;
1632 } amd64_struct4;
1633
1634 LIBTEST_API amd64_struct4 STDCALL 
1635 mono_test_marshal_amd64_pass_return_struct4 (amd64_struct4 s)
1636 {
1637         s.d1 ++;
1638         s.d2 ++;
1639
1640         return s;
1641 }
1642
1643 /*
1644  * IA64 marshalling tests.
1645  */
1646 typedef struct test_struct5 {
1647         float d1, d2;
1648 } test_struct5;
1649
1650 LIBTEST_API test_struct5 STDCALL 
1651 mono_test_marshal_ia64_pass_return_struct5 (double d1, double d2, test_struct5 s, int i, double d3, double d4)
1652 {
1653         s.d1 += d1 + d2 + i;
1654         s.d2 += d3 + d4 + i;
1655
1656         return s;
1657 }
1658
1659 typedef struct test_struct6 {
1660         double d1, d2;
1661 } test_struct6;
1662
1663 LIBTEST_API test_struct6 STDCALL 
1664 mono_test_marshal_ia64_pass_return_struct6 (double d1, double d2, test_struct6 s, int i, double d3, double d4)
1665 {
1666         s.d1 += d1 + d2 + i;
1667         s.d2 += d3 + d4;
1668
1669         return s;
1670 }
1671
1672 static guint32 custom_res [2];
1673
1674 LIBTEST_API void* STDCALL
1675 mono_test_marshal_pass_return_custom (int i, guint32 *ptr, int j)
1676 {
1677         /* ptr will be freed by CleanupNative, so make a copy */
1678         custom_res [0] = 0; /* not allocated by AllocHGlobal */
1679         custom_res [1] = ptr [1];
1680
1681         return &custom_res;
1682 }
1683
1684 LIBTEST_API int STDCALL 
1685 mono_test_marshal_pass_out_custom (int i, guint32 **ptr, int j)
1686 {
1687         custom_res [0] = 0;
1688         custom_res [1] = i + j + 10;
1689
1690         *ptr = custom_res;
1691
1692         return 0;
1693 }
1694
1695 LIBTEST_API int STDCALL 
1696 mono_test_marshal_pass_inout_custom (int i, guint32 *ptr, int j)
1697 {
1698         ptr [0] = 0;
1699         ptr [1] = i + ptr [1] + j;
1700
1701         return 0;
1702 }
1703
1704 LIBTEST_API int STDCALL 
1705 mono_test_marshal_pass_out_byval_custom (int i, guint32 *ptr, int j)
1706 {
1707         return ptr == NULL ? 0 : 1;
1708 }
1709
1710 LIBTEST_API int STDCALL 
1711 mono_test_marshal_pass_byref_custom (int i, guint32 **ptr, int j)
1712 {
1713         (*ptr)[1] += i + j;
1714
1715         return 0;
1716 }
1717
1718 LIBTEST_API void* STDCALL
1719 mono_test_marshal_pass_return_custom2 (int i, guint32 *ptr, int j)
1720 {
1721         g_assert_not_reached ();
1722
1723         return NULL;
1724 }
1725
1726 LIBTEST_API void* STDCALL
1727 mono_test_marshal_pass_return_custom_null (int i, guint32 *ptr, int j)
1728 {
1729         g_assert (ptr == NULL);
1730
1731         return NULL;
1732 }
1733
1734 typedef void *(STDCALL *PassReturnPtrDelegate) (void *ptr);
1735
1736 LIBTEST_API int STDCALL 
1737 mono_test_marshal_pass_return_custom_in_delegate (PassReturnPtrDelegate del)
1738 {
1739         guint32 buf [2];
1740         guint32 res;
1741         guint32 *ptr;
1742
1743         buf [0] = 0;
1744         buf [1] = 10;
1745
1746         ptr = del (&buf);
1747
1748         res = ptr [1];
1749
1750 #ifdef WIN32
1751         /* FIXME: Freed with FreeHGlobal */
1752 #else
1753         g_free (ptr);
1754 #endif
1755
1756         return res;
1757 }
1758
1759 LIBTEST_API int STDCALL 
1760 mono_test_marshal_pass_return_custom_null_in_delegate (PassReturnPtrDelegate del)
1761 {
1762         void *ptr = del (NULL);
1763
1764         return (ptr == NULL) ? 15 : 0;
1765 }
1766
1767 typedef void (STDCALL *CustomOutParamDelegate) (void **pptr);
1768
1769 LIBTEST_API int STDCALL 
1770 mono_test_marshal_custom_out_param_delegate (CustomOutParamDelegate del)
1771 {
1772         void* pptr = del;
1773
1774         del (&pptr);
1775
1776         if(pptr != NULL)
1777                 return 1;
1778
1779         return 0;
1780 }
1781
1782 typedef int (STDCALL *ReturnEnumDelegate) (int e);
1783
1784 LIBTEST_API int STDCALL 
1785 mono_test_marshal_return_enum_delegate (ReturnEnumDelegate func)
1786 {
1787         return func (1);
1788 }
1789
1790 typedef struct {
1791         int a, b, c;
1792         gint64 d;
1793 } BlittableStruct;
1794         
1795 typedef BlittableStruct (STDCALL *SimpleDelegate10) (BlittableStruct ss);
1796
1797 LIBTEST_API int STDCALL 
1798 mono_test_marshal_blittable_struct_delegate (SimpleDelegate10 delegate)
1799 {
1800         BlittableStruct ss, res;
1801
1802         ss.a = 1;
1803         ss.b = 2;
1804         ss.c = 3;
1805         ss.d = 55;
1806
1807         res = delegate (ss);
1808         if (! ((res.a == -1) && (res.b == -2) && (res.c == -3) && (res.d == -55)))
1809                 return 1;
1810
1811         return 0;
1812 }
1813
1814 LIBTEST_API int STDCALL 
1815 mono_test_stdcall_name_mangling (int a, int b, int c)
1816 {
1817         return a + b + c;
1818 }
1819
1820 /*
1821  * PASSING AND RETURNING SMALL STRUCTURES FROM DELEGATES TESTS
1822  */
1823
1824 typedef struct {
1825         int i;
1826 } SmallStruct1;
1827         
1828 typedef SmallStruct1 (STDCALL *SmallStructDelegate1) (SmallStruct1 ss);
1829
1830 LIBTEST_API int STDCALL 
1831 mono_test_marshal_small_struct_delegate1 (SmallStructDelegate1 delegate)
1832 {
1833         SmallStruct1 ss, res;
1834
1835         ss.i = 1;
1836
1837         res = delegate (ss);
1838         if (! (res.i == -1))
1839                 return 1;
1840
1841         return 0;
1842 }
1843
1844 typedef struct {
1845         gint16 i, j;
1846 } SmallStruct2;
1847         
1848 typedef SmallStruct2 (STDCALL *SmallStructDelegate2) (SmallStruct2 ss);
1849
1850 LIBTEST_API int STDCALL 
1851 mono_test_marshal_small_struct_delegate2 (SmallStructDelegate2 delegate)
1852 {
1853         SmallStruct2 ss, res;
1854
1855         ss.i = 2;
1856         ss.j = 3;
1857
1858         res = delegate (ss);
1859         if (! ((res.i == -2) && (res.j == -3)))
1860                 return 1;
1861
1862         return 0;
1863 }
1864
1865 typedef struct {
1866         gint16 i;
1867         gint8 j;
1868 } SmallStruct3;
1869         
1870 typedef SmallStruct3 (STDCALL *SmallStructDelegate3) (SmallStruct3 ss);
1871
1872 LIBTEST_API int STDCALL 
1873 mono_test_marshal_small_struct_delegate3 (SmallStructDelegate3 delegate)
1874 {
1875         SmallStruct3 ss, res;
1876
1877         ss.i = 1;
1878         ss.j = 2;
1879
1880         res = delegate (ss);
1881         if (! ((res.i == -1) && (res.j == -2)))
1882                 return 1;
1883
1884         return 0;
1885 }
1886
1887 typedef struct {
1888         gint16 i;
1889 } SmallStruct4;
1890         
1891 typedef SmallStruct4 (STDCALL *SmallStructDelegate4) (SmallStruct4 ss);
1892
1893 LIBTEST_API int STDCALL 
1894 mono_test_marshal_small_struct_delegate4 (SmallStructDelegate4 delegate)
1895 {
1896         SmallStruct4 ss, res;
1897
1898         ss.i = 1;
1899
1900         res = delegate (ss);
1901         if (! (res.i == -1))
1902                 return 1;
1903
1904         return 0;
1905 }
1906
1907 typedef struct {
1908         gint64 i;
1909 } SmallStruct5;
1910         
1911 typedef SmallStruct5 (STDCALL *SmallStructDelegate5) (SmallStruct5 ss);
1912
1913 LIBTEST_API int STDCALL 
1914 mono_test_marshal_small_struct_delegate5 (SmallStructDelegate5 delegate)
1915 {
1916         SmallStruct5 ss, res;
1917
1918         ss.i = 5;
1919
1920         res = delegate (ss);
1921         if (! (res.i == -5))
1922                 return 1;
1923
1924         return 0;
1925 }
1926
1927 typedef struct {
1928         int i, j;
1929 } SmallStruct6;
1930         
1931 typedef SmallStruct6 (STDCALL *SmallStructDelegate6) (SmallStruct6 ss);
1932
1933 LIBTEST_API int STDCALL 
1934 mono_test_marshal_small_struct_delegate6 (SmallStructDelegate6 delegate)
1935 {
1936         SmallStruct6 ss, res;
1937
1938         ss.i = 1;
1939         ss.j = 2;
1940
1941         res = delegate (ss);
1942         if (! ((res.i == -1) && (res.j == -2)))
1943                 return 1;
1944
1945         return 0;
1946 }
1947
1948 typedef struct {
1949         int i;
1950         gint16 j;
1951 } SmallStruct7;
1952         
1953 typedef SmallStruct7 (STDCALL *SmallStructDelegate7) (SmallStruct7 ss);
1954
1955 LIBTEST_API int STDCALL 
1956 mono_test_marshal_small_struct_delegate7 (SmallStructDelegate7 delegate)
1957 {
1958         SmallStruct7 ss, res;
1959
1960         ss.i = 1;
1961         ss.j = 2;
1962
1963         res = delegate (ss);
1964         if (! ((res.i == -1) && (res.j == -2)))
1965                 return 1;
1966
1967         return 0;
1968 }
1969
1970 typedef struct {
1971         float i;
1972 } SmallStruct8;
1973         
1974 typedef SmallStruct8 (STDCALL *SmallStructDelegate8) (SmallStruct8 ss);
1975
1976 LIBTEST_API int STDCALL 
1977 mono_test_marshal_small_struct_delegate8 (SmallStructDelegate8 delegate)
1978 {
1979         SmallStruct8 ss, res;
1980
1981         ss.i = 1.0;
1982
1983         res = delegate (ss);
1984         if (! ((res.i == -1.0)))
1985                 return 1;
1986
1987         return 0;
1988 }
1989
1990 typedef struct {
1991         double i;
1992 } SmallStruct9;
1993         
1994 typedef SmallStruct9 (STDCALL *SmallStructDelegate9) (SmallStruct9 ss);
1995
1996 LIBTEST_API int STDCALL 
1997 mono_test_marshal_small_struct_delegate9 (SmallStructDelegate9 delegate)
1998 {
1999         SmallStruct9 ss, res;
2000
2001         ss.i = 1.0;
2002
2003         res = delegate (ss);
2004         if (! ((res.i == -1.0)))
2005                 return 1;
2006
2007         return 0;
2008 }
2009
2010 typedef struct {
2011         float i, j;
2012 } SmallStruct10;
2013         
2014 typedef SmallStruct10 (STDCALL *SmallStructDelegate10) (SmallStruct10 ss);
2015
2016 LIBTEST_API int STDCALL 
2017 mono_test_marshal_small_struct_delegate10 (SmallStructDelegate10 delegate)
2018 {
2019         SmallStruct10 ss, res;
2020
2021         ss.i = 1.0;
2022         ss.j = 2.0;
2023
2024         res = delegate (ss);
2025         if (! ((res.i == -1.0) && (res.j == -2.0)))
2026                 return 1;
2027
2028         return 0;
2029 }
2030
2031 typedef struct {
2032         float i;
2033         int j;
2034 } SmallStruct11;
2035         
2036 typedef SmallStruct11 (STDCALL *SmallStructDelegate11) (SmallStruct11 ss);
2037
2038 LIBTEST_API int STDCALL 
2039 mono_test_marshal_small_struct_delegate11 (SmallStructDelegate11 delegate)
2040 {
2041         SmallStruct11 ss, res;
2042
2043         ss.i = 1.0;
2044         ss.j = 2;
2045
2046         res = delegate (ss);
2047         if (! ((res.i == -1.0) && (res.j == -2)))
2048                 return 1;
2049
2050         return 0;
2051 }
2052
2053 typedef int (STDCALL *ArrayDelegate) (int i, char *j, void *arr);
2054
2055 LIBTEST_API int STDCALL 
2056 mono_test_marshal_array_delegate (void *arr, int len, ArrayDelegate del)
2057 {
2058         return del (len, NULL, arr);
2059 }
2060
2061 typedef int (STDCALL *ArrayDelegateLong) (gint64 i, char *j, void *arr);
2062
2063 LIBTEST_API int STDCALL 
2064 mono_test_marshal_array_delegate_long (void *arr, gint64 len, ArrayDelegateLong del)
2065 {
2066         return del (len, NULL, arr);
2067 }
2068
2069 LIBTEST_API int STDCALL 
2070 mono_test_marshal_out_array_delegate (int *arr, int len, ArrayDelegate del)
2071 {
2072         del (len, NULL, arr);
2073
2074         if ((arr [0] != 1) || (arr [1] != 2))
2075                 return 1;
2076         else
2077                 return 0;
2078 }
2079
2080 typedef gunichar2* (STDCALL *UnicodeStringDelegate) (gunichar2 *message);
2081
2082 LIBTEST_API int STDCALL 
2083 mono_test_marshal_return_unicode_string_delegate (UnicodeStringDelegate del)
2084 {
2085         const char m[] = "abcdef";
2086         gunichar2 *s2, *res;
2087         glong len;
2088
2089         s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
2090
2091         res = del (s2);
2092
2093         marshal_free (res);
2094
2095         return 0;
2096 }
2097
2098 LIBTEST_API int STDCALL 
2099 mono_test_marshal_out_string_array_delegate (char **arr, int len, ArrayDelegate del)
2100 {
2101         del (len, NULL, arr);
2102
2103         if (!strcmp (arr [0], "ABC") && !strcmp (arr [1], "DEF"))
2104                 return 0;
2105         else
2106                 return 1;
2107 }
2108
2109 typedef int (*CdeclDelegate) (int i, int j);
2110
2111 LIBTEST_API int STDCALL 
2112 mono_test_marshal_cdecl_delegate (CdeclDelegate del)
2113 {
2114         int i;
2115
2116         for (i = 0; i < 1000; ++i)
2117                 del (1, 2);
2118
2119         return 0;
2120 }
2121
2122 typedef char** (STDCALL *ReturnStringArrayDelegate) (int i);
2123
2124 LIBTEST_API int STDCALL 
2125 mono_test_marshal_return_string_array_delegate (ReturnStringArrayDelegate d)
2126 {
2127         char **arr = d (2);
2128         int res;
2129
2130         if (arr == NULL)
2131                 return 3;
2132
2133         if (strcmp (arr [0], "ABC") || strcmp (arr [1], "DEF"))
2134                 res = 1;
2135         else
2136                 res = 0;
2137
2138         marshal_free (arr);
2139
2140         return res;
2141 }
2142
2143 typedef int (STDCALL *ByrefStringDelegate) (char **s);
2144
2145 LIBTEST_API int STDCALL 
2146 mono_test_marshal_byref_string_delegate (ByrefStringDelegate d)
2147 {
2148         char *s = (char*)"ABC";
2149         int res;
2150
2151         res = d (&s);
2152         if (res != 0)
2153                 return res;
2154
2155         if (!strcmp (s, "DEF"))
2156                 res = 0;
2157         else
2158                 res = 2;
2159
2160         marshal_free (s);
2161
2162         return res;
2163 }
2164
2165 LIBTEST_API int STDCALL 
2166 add_delegate (int i, int j)
2167 {
2168         return i + j;
2169 }
2170
2171 LIBTEST_API gpointer STDCALL 
2172 mono_test_marshal_return_fnptr (void)
2173 {
2174         return &add_delegate;
2175 }
2176
2177 LIBTEST_API int STDCALL 
2178 mono_xr (int code)
2179 {
2180         printf ("codigo %x\n", code);
2181         return code + 1234;
2182 }
2183
2184 typedef struct {
2185         int handle;
2186 } HandleRef;
2187
2188 LIBTEST_API HandleRef STDCALL 
2189 mono_xr_as_handle (int code)
2190 {
2191         HandleRef ref;
2192
2193         memset (&ref, 0, sizeof (ref));
2194
2195         return ref;
2196 }
2197  
2198 typedef struct {
2199         int   a;
2200         void *handle1;
2201         void *handle2;
2202         int   b;
2203 } HandleStructs;
2204
2205 LIBTEST_API int STDCALL 
2206 mono_safe_handle_struct_ref (HandleStructs *x)
2207 {
2208         printf ("Dingus Ref! \n");
2209         printf ("Values: %d %d %p %p\n", x->a, x->b, x->handle1, x->handle2);
2210         if (x->a != 1234)
2211                 return 1;
2212         if (x->b != 8743)
2213                 return 2;
2214
2215         if (x->handle1 != (void*) 0x7080feed)
2216                 return 3;
2217
2218         if (x->handle2 != (void*) 0x1234abcd)
2219                 return 4;
2220
2221         return 0xf00d;
2222 }
2223
2224 LIBTEST_API int STDCALL 
2225 mono_safe_handle_struct (HandleStructs x)
2226 {
2227         printf ("Dingus Standard! \n");
2228         printf ("Values: %d %d %p %p\n", x.a, x.b, x.handle1, x.handle2);
2229         if (x.a != 1234)
2230                 return 1;
2231         if (x.b != 8743)
2232                 return 2;
2233
2234         if (x.handle1 != (void*) 0x7080feed)
2235                 return 3;
2236
2237         if (x.handle2 != (void*) 0x1234abcd)
2238                 return 4;
2239         
2240         return 0xf00f;
2241 }
2242
2243 typedef struct {
2244         void *a;
2245 } TrivialHandle;
2246
2247 LIBTEST_API int STDCALL 
2248 mono_safe_handle_struct_simple (TrivialHandle x)
2249 {
2250         printf ("The value is %p\n", x.a);
2251         return ((int)(gsize)x.a) * 2;
2252 }
2253
2254 LIBTEST_API int STDCALL 
2255 mono_safe_handle_return (void)
2256 {
2257         return 0x1000f00d;
2258 }
2259
2260 LIBTEST_API void STDCALL
2261 mono_safe_handle_ref (void **handle)
2262 {
2263         if (*handle != 0){
2264                 *handle = (void *) 0xbad;
2265                 return;
2266         }
2267
2268         *handle = (void *) 0x800d;
2269 }
2270 /*
2271  * COM INTEROP TESTS
2272  */
2273
2274 #ifndef WIN32
2275
2276 typedef struct {
2277         guint16 vt;
2278         guint16 wReserved1;
2279         guint16 wReserved2;
2280         guint16 wReserved3;
2281         union {
2282                 gint64 llVal;
2283                 gint32 lVal;
2284                 guint8  bVal;
2285                 gint16 iVal;
2286                 float  fltVal;
2287                 double dblVal;
2288                 gint16 boolVal;
2289                 gunichar2* bstrVal;
2290                 gint8 cVal;
2291                 guint16 uiVal;
2292                 guint32 ulVal;
2293                 guint64 ullVal;
2294                 struct {
2295                         gpointer pvRecord;
2296                         gpointer pRecInfo;
2297                 };
2298         };
2299 } VARIANT;
2300
2301 typedef enum {
2302         VARIANT_TRUE = -1,
2303         VARIANT_FALSE = 0
2304 } VariantBool;
2305
2306 typedef enum {
2307         VT_EMPTY = 0,
2308         VT_NULL = 1,
2309         VT_I2 = 2,
2310         VT_I4 = 3,
2311         VT_R4 = 4,
2312         VT_R8 = 5,
2313         VT_CY = 6,
2314         VT_DATE = 7,
2315         VT_BSTR = 8,
2316         VT_DISPATCH = 9,
2317         VT_ERROR = 10,
2318         VT_BOOL = 11,
2319         VT_VARIANT = 12,
2320         VT_UNKNOWN = 13,
2321         VT_DECIMAL = 14,
2322         VT_I1 = 16,
2323         VT_UI1 = 17,
2324         VT_UI2 = 18,
2325         VT_UI4 = 19,
2326         VT_I8 = 20,
2327         VT_UI8 = 21,
2328         VT_INT = 22,
2329         VT_UINT = 23,
2330         VT_VOID = 24,
2331         VT_HRESULT = 25,
2332         VT_PTR = 26,
2333         VT_SAFEARRAY = 27,
2334         VT_CARRAY = 28,
2335         VT_USERDEFINED = 29,
2336         VT_LPSTR = 30,
2337         VT_LPWSTR = 31,
2338         VT_RECORD = 36,
2339         VT_FILETIME = 64,
2340         VT_BLOB = 65,
2341         VT_STREAM = 66,
2342         VT_STORAGE = 67,
2343         VT_STREAMED_OBJECT = 68,
2344         VT_STORED_OBJECT = 69,
2345         VT_BLOB_OBJECT = 70,
2346         VT_CF = 71,
2347         VT_CLSID = 72,
2348         VT_VECTOR = 4096,
2349         VT_ARRAY = 8192,
2350         VT_BYREF = 16384
2351 } VarEnum;
2352
2353 void VariantInit(VARIANT* vt)
2354 {
2355         vt->vt = VT_EMPTY;
2356 }
2357
2358 typedef struct
2359 {
2360         guint32 a;
2361         guint16 b;
2362         guint16 c;
2363         guint8 d[8];
2364 } GUID;
2365
2366 #define S_OK 0
2367
2368 #endif
2369
2370 LIBTEST_API int STDCALL 
2371 mono_test_marshal_bstr_in(gunichar2* bstr)
2372 {
2373         gint32 result = 0;
2374         gchar* bstr_utf8 = g_utf16_to_utf8 (bstr, -1, NULL, NULL, NULL);
2375         result = strcmp("mono_test_marshal_bstr_in", bstr_utf8);
2376         g_free(bstr_utf8);
2377         if (result == 0)
2378                 return 0;
2379         return 1;
2380 }
2381
2382 LIBTEST_API int STDCALL 
2383 mono_test_marshal_bstr_out(gunichar2** bstr)
2384 {
2385         *bstr = marshal_bstr_alloc ("mono_test_marshal_bstr_out");
2386         return 0;
2387 }
2388
2389 LIBTEST_API int STDCALL 
2390 mono_test_marshal_bstr_in_null(gunichar2* bstr)
2391 {
2392         if (!bstr)
2393                 return 0;
2394         return 1;
2395 }
2396
2397 LIBTEST_API int STDCALL 
2398 mono_test_marshal_bstr_out_null(gunichar2** bstr)
2399 {
2400         *bstr = NULL;
2401         return 0;
2402 }
2403
2404 LIBTEST_API int STDCALL 
2405 mono_test_marshal_variant_in_sbyte(VARIANT variant)
2406 {
2407         if (variant.vt == VT_I1 && variant.cVal == 100)
2408                 return 0;
2409         return 1;
2410 }
2411
2412 LIBTEST_API int STDCALL 
2413 mono_test_marshal_variant_in_byte(VARIANT variant)
2414 {
2415         if (variant.vt == VT_UI1 && variant.bVal == 100)
2416                 return 0;
2417         return 1;
2418 }
2419
2420 LIBTEST_API int STDCALL 
2421 mono_test_marshal_variant_in_short(VARIANT variant)
2422 {
2423         if (variant.vt == VT_I2 && variant.iVal == 314)
2424                 return 0;
2425         return 1;
2426 }
2427
2428 LIBTEST_API int STDCALL 
2429 mono_test_marshal_variant_in_ushort(VARIANT variant)
2430 {
2431         if (variant.vt == VT_UI2 && variant.uiVal == 314)
2432                 return 0;
2433         return 1;
2434 }
2435
2436 LIBTEST_API int STDCALL 
2437 mono_test_marshal_variant_in_int(VARIANT variant)
2438 {
2439         if (variant.vt == VT_I4 && variant.lVal == 314)
2440                 return 0;
2441         return 1;
2442 }
2443
2444 LIBTEST_API int STDCALL 
2445 mono_test_marshal_variant_in_uint(VARIANT variant)
2446 {
2447         if (variant.vt == VT_UI4 && variant.ulVal == 314)
2448                 return 0;
2449         return 1;
2450 }
2451
2452 LIBTEST_API int STDCALL 
2453 mono_test_marshal_variant_in_long(VARIANT variant)
2454 {
2455         if (variant.vt == VT_I8 && variant.llVal == 314)
2456                 return 0;
2457         return 1;
2458 }
2459
2460 LIBTEST_API int STDCALL 
2461 mono_test_marshal_variant_in_ulong(VARIANT variant)
2462 {
2463         if (variant.vt == VT_UI8 && variant.ullVal == 314)
2464                 return 0;
2465         return 1;
2466 }
2467
2468 LIBTEST_API int STDCALL 
2469 mono_test_marshal_variant_in_float(VARIANT variant)
2470 {
2471         if (variant.vt == VT_R4 && (variant.fltVal - 3.14)/3.14 < .001)
2472                 return 0;
2473         return 1;
2474 }
2475
2476 LIBTEST_API int STDCALL 
2477 mono_test_marshal_variant_in_double(VARIANT variant)
2478 {
2479         if (variant.vt == VT_R8 && (variant.dblVal - 3.14)/3.14 < .001)
2480                 return 0;
2481         return 1;
2482 }
2483
2484 LIBTEST_API int STDCALL 
2485 mono_test_marshal_variant_in_bstr(VARIANT variant)
2486 {
2487         gint32 result = 0;
2488         gchar* bstr_utf8 = g_utf16_to_utf8 (variant.bstrVal, -1, NULL, NULL, NULL);
2489         result = strcmp("PI", bstr_utf8);
2490         g_free(bstr_utf8);
2491
2492         if (variant.vt == VT_BSTR && !result)
2493                 return 0;
2494         return 1;
2495 }
2496
2497 LIBTEST_API int STDCALL 
2498 mono_test_marshal_variant_in_bool_true (VARIANT variant)
2499 {
2500         if (variant.vt == VT_BOOL && variant.boolVal == VARIANT_TRUE)
2501                 return 0;
2502         return 1;
2503 }
2504
2505 LIBTEST_API int STDCALL 
2506 mono_test_marshal_variant_in_bool_false (VARIANT variant)
2507 {
2508         if (variant.vt == VT_BOOL && variant.boolVal == VARIANT_FALSE)
2509                 return 0;
2510         return 1;
2511 }
2512
2513 LIBTEST_API int STDCALL 
2514 mono_test_marshal_variant_out_sbyte(VARIANT* variant)
2515 {
2516         variant->vt = VT_I1;
2517         variant->cVal = 100;
2518
2519         return 0;
2520 }
2521
2522 LIBTEST_API int STDCALL 
2523 mono_test_marshal_variant_out_byte(VARIANT* variant)
2524 {       
2525         variant->vt = VT_UI1;
2526         variant->bVal = 100;
2527
2528         return 0;
2529 }
2530
2531 LIBTEST_API int STDCALL 
2532 mono_test_marshal_variant_out_short(VARIANT* variant)
2533 {
2534         variant->vt = VT_I2;
2535         variant->iVal = 314;
2536
2537         return 0;
2538 }
2539
2540 LIBTEST_API int STDCALL 
2541 mono_test_marshal_variant_out_ushort(VARIANT* variant)
2542 {
2543         variant->vt = VT_UI2;
2544         variant->uiVal = 314;
2545
2546         return 0;
2547 }
2548
2549 LIBTEST_API int STDCALL 
2550 mono_test_marshal_variant_out_int(VARIANT* variant)
2551 {
2552         variant->vt = VT_I4;
2553         variant->lVal = 314;
2554
2555         return 0;
2556 }
2557
2558 LIBTEST_API int STDCALL 
2559 mono_test_marshal_variant_out_uint(VARIANT* variant)
2560 {
2561         variant->vt = VT_UI4;
2562         variant->ulVal = 314;
2563
2564         return 0;
2565 }
2566
2567 LIBTEST_API int STDCALL 
2568 mono_test_marshal_variant_out_long(VARIANT* variant)
2569 {
2570         variant->vt = VT_I8;
2571         variant->llVal = 314;
2572
2573         return 0;
2574 }
2575
2576 LIBTEST_API int STDCALL 
2577 mono_test_marshal_variant_out_ulong(VARIANT* variant)
2578 {
2579         variant->vt = VT_UI8;
2580         variant->ullVal = 314;
2581
2582         return 0;
2583 }
2584
2585 LIBTEST_API int STDCALL 
2586 mono_test_marshal_variant_out_float(VARIANT* variant)
2587 {
2588         variant->vt = VT_R4;
2589         variant->fltVal = 3.14;
2590
2591         return 0;
2592 }
2593
2594 LIBTEST_API int STDCALL 
2595 mono_test_marshal_variant_out_double(VARIANT* variant)
2596 {
2597         variant->vt = VT_R8;
2598         variant->dblVal = 3.14;
2599
2600         return 0;
2601 }
2602
2603 LIBTEST_API int STDCALL 
2604 mono_test_marshal_variant_out_bstr(VARIANT* variant)
2605 {
2606         variant->vt = VT_BSTR;
2607         variant->bstrVal = marshal_bstr_alloc("PI");
2608
2609         return 0;
2610 }
2611
2612 LIBTEST_API int STDCALL 
2613 mono_test_marshal_variant_out_bool_true (VARIANT* variant)
2614 {
2615         variant->vt = VT_BOOL;
2616         variant->boolVal = VARIANT_TRUE;
2617
2618         return 0;
2619 }
2620
2621 LIBTEST_API int STDCALL 
2622 mono_test_marshal_variant_out_bool_false (VARIANT* variant)
2623 {
2624         variant->vt = VT_BOOL;
2625         variant->boolVal = VARIANT_FALSE;
2626
2627         return 0;
2628 }
2629
2630 typedef int (STDCALL *VarFunc) (int vt, VARIANT variant);
2631 typedef int (STDCALL *VarRefFunc) (int vt, VARIANT* variant);
2632
2633 LIBTEST_API int STDCALL 
2634 mono_test_marshal_variant_in_sbyte_unmanaged(VarFunc func)
2635 {
2636         VARIANT vt;
2637         vt.vt = VT_I1;
2638         vt.cVal = -100;
2639         return func (VT_I1, vt);
2640 }
2641
2642 LIBTEST_API int STDCALL 
2643 mono_test_marshal_variant_in_byte_unmanaged(VarFunc func)
2644 {
2645         VARIANT vt;
2646         vt.vt = VT_UI1;
2647         vt.bVal = 100;
2648         return func (VT_UI1, vt);
2649 }
2650
2651 LIBTEST_API int STDCALL 
2652 mono_test_marshal_variant_in_short_unmanaged(VarFunc func)
2653 {
2654         VARIANT vt;
2655         vt.vt = VT_I2;
2656         vt.iVal = -100;
2657         return func (VT_I2, vt);
2658 }
2659
2660 LIBTEST_API int STDCALL 
2661 mono_test_marshal_variant_in_ushort_unmanaged(VarFunc func)
2662 {
2663         VARIANT vt;
2664         vt.vt = VT_UI2;
2665         vt.uiVal = 100;
2666         return func (VT_UI2, vt);
2667 }
2668
2669 LIBTEST_API int STDCALL 
2670 mono_test_marshal_variant_in_int_unmanaged(VarFunc func)
2671 {
2672         VARIANT vt;
2673         vt.vt = VT_I4;
2674         vt.lVal = -100;
2675         return func (VT_I4, vt);
2676 }
2677
2678 LIBTEST_API int STDCALL 
2679 mono_test_marshal_variant_in_uint_unmanaged(VarFunc func)
2680 {
2681         VARIANT vt;
2682         vt.vt = VT_UI4;
2683         vt.ulVal = 100;
2684         return func (VT_UI4, vt);
2685 }
2686
2687 LIBTEST_API int STDCALL 
2688 mono_test_marshal_variant_in_long_unmanaged(VarFunc func)
2689 {
2690         VARIANT vt;
2691         vt.vt = VT_I8;
2692         vt.llVal = -100;
2693         return func (VT_I8, vt);
2694 }
2695
2696 LIBTEST_API int STDCALL 
2697 mono_test_marshal_variant_in_ulong_unmanaged(VarFunc func)
2698 {
2699         VARIANT vt;
2700         vt.vt = VT_UI8;
2701         vt.ullVal = 100;
2702         return func (VT_UI8, vt);
2703 }
2704
2705 LIBTEST_API int STDCALL 
2706 mono_test_marshal_variant_in_float_unmanaged(VarFunc func)
2707 {
2708         VARIANT vt;
2709         vt.vt = VT_R4;
2710         vt.fltVal = 3.14;
2711         return func (VT_R4, vt);
2712 }
2713
2714 LIBTEST_API int STDCALL 
2715 mono_test_marshal_variant_in_double_unmanaged(VarFunc func)
2716 {
2717         VARIANT vt;
2718         vt.vt = VT_R8;
2719         vt.dblVal = 3.14;
2720         return func (VT_R8, vt);
2721 }
2722
2723 LIBTEST_API int STDCALL 
2724 mono_test_marshal_variant_in_bstr_unmanaged(VarFunc func)
2725 {
2726         VARIANT vt;
2727         vt.vt = VT_BSTR;
2728         vt.bstrVal = marshal_bstr_alloc("PI");
2729         return func (VT_BSTR, vt);
2730 }
2731
2732 LIBTEST_API int STDCALL 
2733 mono_test_marshal_variant_in_bool_true_unmanaged(VarFunc func)
2734 {
2735         VARIANT vt;
2736         vt.vt = VT_BOOL;
2737         vt.boolVal = VARIANT_TRUE;
2738         return func (VT_BOOL, vt);
2739 }
2740
2741 LIBTEST_API int STDCALL 
2742 mono_test_marshal_variant_in_bool_false_unmanaged(VarFunc func)
2743 {
2744         VARIANT vt;
2745         vt.vt = VT_BOOL;
2746         vt.boolVal = VARIANT_FALSE;
2747         return func (VT_BOOL, vt);
2748 }
2749
2750 LIBTEST_API int STDCALL 
2751 mono_test_marshal_variant_out_sbyte_unmanaged(VarRefFunc func)
2752 {
2753         VARIANT vt;
2754         VariantInit (&vt);
2755         func (VT_I1, &vt);
2756         if (vt.vt == VT_I1 && vt.cVal == -100)
2757                 return 0;
2758         return 1;
2759 }
2760
2761 LIBTEST_API int STDCALL 
2762 mono_test_marshal_variant_out_byte_unmanaged(VarRefFunc func)
2763 {
2764         VARIANT vt;
2765         VariantInit (&vt);
2766         func (VT_UI1, &vt);
2767         if (vt.vt == VT_UI1 && vt.bVal == 100)
2768                 return 0;
2769         return 1;
2770 }
2771
2772 LIBTEST_API int STDCALL 
2773 mono_test_marshal_variant_out_short_unmanaged(VarRefFunc func)
2774 {
2775         VARIANT vt;
2776         VariantInit (&vt);
2777         func (VT_I2, &vt);
2778         if (vt.vt == VT_I2 && vt.iVal == -100)
2779                 return 0;
2780         return 1;
2781 }
2782
2783 LIBTEST_API int STDCALL 
2784 mono_test_marshal_variant_out_ushort_unmanaged(VarRefFunc func)
2785 {
2786         VARIANT vt;
2787         VariantInit (&vt);
2788         func (VT_UI2, &vt);
2789         if (vt.vt == VT_UI2 && vt.uiVal == 100)
2790                 return 0;
2791         return 1;
2792 }
2793
2794 LIBTEST_API int STDCALL 
2795 mono_test_marshal_variant_out_int_unmanaged(VarRefFunc func)
2796 {
2797         VARIANT vt;
2798         VariantInit (&vt);
2799         func (VT_I4, &vt);
2800         if (vt.vt == VT_I4 && vt.lVal == -100)
2801                 return 0;
2802         return 1;
2803 }
2804
2805 LIBTEST_API int STDCALL 
2806 mono_test_marshal_variant_out_uint_unmanaged(VarRefFunc func)
2807 {
2808         VARIANT vt;
2809         VariantInit (&vt);
2810         func (VT_UI4, &vt);
2811         if (vt.vt == VT_UI4 && vt.ulVal == 100)
2812                 return 0;
2813         return 1;
2814 }
2815
2816 LIBTEST_API int STDCALL 
2817 mono_test_marshal_variant_out_long_unmanaged(VarRefFunc func)
2818 {
2819         VARIANT vt;
2820         VariantInit (&vt);
2821         func (VT_I8, &vt);
2822         if (vt.vt == VT_I8 && vt.llVal == -100)
2823                 return 0;
2824         return 1;
2825 }
2826
2827 LIBTEST_API int STDCALL 
2828 mono_test_marshal_variant_out_ulong_unmanaged(VarRefFunc func)
2829 {
2830         VARIANT vt;
2831         VariantInit (&vt);
2832         func (VT_UI8, &vt);
2833         if (vt.vt == VT_UI8 && vt.ullVal == 100)
2834                 return 0;
2835         return 1;
2836 }
2837
2838 LIBTEST_API int STDCALL 
2839 mono_test_marshal_variant_out_float_unmanaged(VarRefFunc func)
2840 {
2841         VARIANT vt;
2842         VariantInit (&vt);
2843         func (VT_R4, &vt);
2844         if (vt.vt == VT_R4 && fabs (vt.fltVal - 3.14f) < 1e-10)
2845                 return 0;
2846         return 1;
2847 }
2848
2849 LIBTEST_API int STDCALL 
2850 mono_test_marshal_variant_out_double_unmanaged(VarRefFunc func)
2851 {
2852         VARIANT vt;
2853         VariantInit (&vt);
2854         func (VT_R8, &vt);
2855         if (vt.vt == VT_R8 && fabs (vt.dblVal - 3.14) < 1e-10)
2856                 return 0;
2857         return 1;
2858 }
2859
2860 LIBTEST_API int STDCALL 
2861 mono_test_marshal_variant_out_bstr_unmanaged(VarRefFunc func)
2862 {
2863         VARIANT vt;
2864         gchar* bstr_utf8;
2865         gint32 result = 0;
2866
2867
2868         VariantInit (&vt);
2869         func (VT_BSTR, &vt);
2870         bstr_utf8 = g_utf16_to_utf8 (vt.bstrVal, -1, NULL, NULL, NULL);
2871         result = strcmp("PI", bstr_utf8);
2872         g_free(bstr_utf8);
2873         if (vt.vt == VT_BSTR && !result)
2874                 return 0;
2875         return 1;
2876 }
2877
2878 LIBTEST_API int STDCALL 
2879 mono_test_marshal_variant_out_bool_true_unmanaged(VarRefFunc func)
2880 {
2881         VARIANT vt;
2882         VariantInit (&vt);
2883         func (VT_BOOL, &vt);
2884         if (vt.vt == VT_BOOL && vt.boolVal == VARIANT_TRUE)
2885                 return 0;
2886         return 1;
2887 }
2888
2889 LIBTEST_API int STDCALL 
2890 mono_test_marshal_variant_out_bool_false_unmanaged(VarRefFunc func)
2891 {
2892         VARIANT vt;
2893         VariantInit (&vt);
2894         func (VT_BOOL, &vt);
2895         if (vt.vt == VT_BOOL && vt.boolVal == VARIANT_TRUE)
2896                 return 0;
2897         return 1;
2898 }
2899
2900 typedef struct MonoComObject MonoComObject;
2901
2902 typedef struct
2903 {
2904         int (STDCALL *QueryInterface)(MonoComObject* pUnk, gpointer riid, gpointer* ppv);
2905         int (STDCALL *AddRef)(MonoComObject* pUnk);
2906         int (STDCALL *Release)(MonoComObject* pUnk);
2907         int (STDCALL *get_ITest)(MonoComObject* pUnk, MonoComObject* *ppUnk);
2908         int (STDCALL *SByteIn)(MonoComObject* pUnk, char a);
2909         int (STDCALL *ByteIn)(MonoComObject* pUnk, unsigned char a);
2910         int (STDCALL *ShortIn)(MonoComObject* pUnk, short a);
2911         int (STDCALL *UShortIn)(MonoComObject* pUnk, unsigned short a);
2912         int (STDCALL *IntIn)(MonoComObject* pUnk, int a);
2913         int (STDCALL *UIntIn)(MonoComObject* pUnk, unsigned int a);
2914         int (STDCALL *LongIn)(MonoComObject* pUnk, gint64 a);
2915         int (STDCALL *ULongIn)(MonoComObject* pUnk, guint64 a);
2916         int (STDCALL *FloatIn)(MonoComObject* pUnk, float a);
2917         int (STDCALL *DoubleIn)(MonoComObject* pUnk, double a);
2918         int (STDCALL *ITestIn)(MonoComObject* pUnk, MonoComObject* pUnk2);
2919         int (STDCALL *ITestOut)(MonoComObject* pUnk, MonoComObject* *ppUnk);
2920 } MonoIUnknown;
2921
2922 struct MonoComObject
2923 {
2924         MonoIUnknown* vtbl;
2925         int m_ref;
2926 };
2927
2928 static GUID IID_ITest = {0, 0, 0, {0,0,0,0,0,0,0,1}};
2929 static GUID IID_IMonoUnknown = {0, 0, 0, {0xc0,0,0,0,0,0,0,0x46}};
2930 static GUID IID_IMonoDispatch = {0x00020400, 0, 0, {0xc0,0,0,0,0,0,0,0x46}};
2931
2932 LIBTEST_API int STDCALL
2933 MonoQueryInterface(MonoComObject* pUnk, gpointer riid, gpointer* ppv)
2934 {
2935
2936         *ppv = NULL;
2937         if (!memcmp(riid, &IID_IMonoUnknown, sizeof(GUID))) {
2938                 *ppv = pUnk;
2939                 return S_OK;
2940         }
2941         else if (!memcmp(riid, &IID_ITest, sizeof(GUID))) {
2942                 *ppv = pUnk;
2943                 return S_OK;
2944         }
2945         else if (!memcmp(riid, &IID_IMonoDispatch, sizeof(GUID))) {
2946                 *ppv = pUnk;
2947                 return S_OK;
2948         }
2949         return 0x80004002; //E_NOINTERFACE;
2950 }
2951
2952 LIBTEST_API int STDCALL 
2953 MonoAddRef(MonoComObject* pUnk)
2954 {
2955         return ++(pUnk->m_ref);
2956 }
2957
2958 LIBTEST_API int STDCALL 
2959 MonoRelease(MonoComObject* pUnk)
2960 {
2961         return --(pUnk->m_ref);
2962 }
2963
2964 LIBTEST_API int STDCALL 
2965 SByteIn(MonoComObject* pUnk, char a)
2966 {
2967         return S_OK;
2968 }
2969
2970 LIBTEST_API int STDCALL 
2971 ByteIn(MonoComObject* pUnk, unsigned char a)
2972 {
2973         return S_OK;
2974 }
2975
2976 LIBTEST_API int STDCALL 
2977 ShortIn(MonoComObject* pUnk, short a)
2978 {
2979         return S_OK;
2980 }
2981
2982 LIBTEST_API int STDCALL 
2983 UShortIn(MonoComObject* pUnk, unsigned short a)
2984 {
2985         return S_OK;
2986 }
2987
2988 LIBTEST_API int STDCALL 
2989 IntIn(MonoComObject* pUnk, int a)
2990 {
2991         return S_OK;
2992 }
2993
2994 LIBTEST_API int STDCALL 
2995 UIntIn(MonoComObject* pUnk, unsigned int a)
2996 {
2997         return S_OK;
2998 }
2999
3000 LIBTEST_API int STDCALL 
3001 LongIn(MonoComObject* pUnk, gint64 a)
3002 {
3003         return S_OK;
3004 }
3005
3006 LIBTEST_API int STDCALL 
3007 ULongIn(MonoComObject* pUnk, guint64 a)
3008 {
3009         return S_OK;
3010 }
3011
3012 LIBTEST_API int STDCALL 
3013 FloatIn(MonoComObject* pUnk, float a)
3014 {
3015         return S_OK;
3016 }
3017
3018 LIBTEST_API int STDCALL 
3019 DoubleIn(MonoComObject* pUnk, double a)
3020 {
3021         return S_OK;
3022 }
3023
3024 LIBTEST_API int STDCALL 
3025 ITestIn(MonoComObject* pUnk, MonoComObject *pUnk2)
3026 {
3027         return S_OK;
3028 }
3029
3030 LIBTEST_API int STDCALL 
3031 ITestOut(MonoComObject* pUnk, MonoComObject* *ppUnk)
3032 {
3033         return S_OK;
3034 }
3035
3036 LIBTEST_API int STDCALL 
3037 get_ITest(MonoComObject* pUnk, MonoComObject* *ppUnk)
3038 {
3039         return S_OK;
3040 }
3041
3042 static void create_com_object (MonoComObject** pOut)
3043 {
3044         *pOut = g_new0 (MonoComObject, 1);
3045         (*pOut)->vtbl = g_new0 (MonoIUnknown, 1);
3046
3047         (*pOut)->m_ref = 1;
3048         (*pOut)->vtbl->QueryInterface = MonoQueryInterface;
3049         (*pOut)->vtbl->AddRef = MonoAddRef;
3050         (*pOut)->vtbl->Release = MonoRelease;
3051         (*pOut)->vtbl->SByteIn = SByteIn;
3052         (*pOut)->vtbl->ByteIn = ByteIn;
3053         (*pOut)->vtbl->ShortIn = ShortIn;
3054         (*pOut)->vtbl->UShortIn = UShortIn;
3055         (*pOut)->vtbl->IntIn = IntIn;
3056         (*pOut)->vtbl->UIntIn = UIntIn;
3057         (*pOut)->vtbl->LongIn = LongIn;
3058         (*pOut)->vtbl->ULongIn = ULongIn;
3059         (*pOut)->vtbl->FloatIn = FloatIn;
3060         (*pOut)->vtbl->DoubleIn = DoubleIn;
3061         (*pOut)->vtbl->ITestIn = ITestIn;
3062         (*pOut)->vtbl->ITestOut = ITestOut;
3063         (*pOut)->vtbl->get_ITest = get_ITest;
3064 }
3065
3066 static MonoComObject* same_object = NULL;
3067
3068 LIBTEST_API int STDCALL 
3069 mono_test_marshal_com_object_create(MonoComObject* *pUnk)
3070 {
3071         create_com_object (pUnk);
3072
3073         if (!same_object)
3074                 same_object = *pUnk;
3075
3076         return 0;
3077 }
3078
3079 LIBTEST_API int STDCALL 
3080 mono_test_marshal_com_object_same(MonoComObject* *pUnk)
3081 {
3082         *pUnk = same_object;
3083
3084         return 0;
3085 }
3086
3087 LIBTEST_API int STDCALL 
3088 mono_test_marshal_com_object_destroy(MonoComObject *pUnk)
3089 {
3090         int ref = --(pUnk->m_ref);
3091         g_free(pUnk->vtbl);
3092         g_free(pUnk);
3093
3094         return ref;
3095 }
3096
3097 LIBTEST_API int STDCALL 
3098 mono_test_marshal_com_object_ref_count(MonoComObject *pUnk)
3099 {
3100         return pUnk->m_ref;
3101 }
3102
3103 LIBTEST_API int STDCALL 
3104 mono_test_marshal_ccw_itest (MonoComObject *pUnk)
3105 {
3106         int hr = 0;
3107         MonoComObject* pTest;
3108
3109         if (!pUnk)
3110                 return 1;
3111
3112         hr = pUnk->vtbl->SByteIn (pUnk, -100);
3113         if (hr != 0)
3114                 return 2;
3115         hr = pUnk->vtbl->ByteIn (pUnk, 100);
3116         if (hr != 0)
3117                 return 3;
3118         hr = pUnk->vtbl->ShortIn (pUnk, -100);
3119         if (hr != 0)
3120                 return 4;
3121         hr = pUnk->vtbl->UShortIn (pUnk, 100);
3122         if (hr != 0)
3123                 return 5;
3124         hr = pUnk->vtbl->IntIn (pUnk, -100);
3125         if (hr != 0)
3126                 return 6;
3127         hr = pUnk->vtbl->UIntIn (pUnk, 100);
3128         if (hr != 0)
3129                 return 7;
3130         hr = pUnk->vtbl->LongIn (pUnk, -100);
3131         if (hr != 0)
3132                 return 8;
3133         hr = pUnk->vtbl->ULongIn (pUnk, 100);
3134         if (hr != 0)
3135                 return 9;
3136         hr = pUnk->vtbl->FloatIn (pUnk, 3.14f);
3137         if (hr != 0)
3138                 return 10;
3139         hr = pUnk->vtbl->DoubleIn (pUnk, 3.14);
3140         if (hr != 0)
3141                 return 11;
3142         hr = pUnk->vtbl->ITestIn (pUnk, pUnk);
3143         if (hr != 0)
3144                 return 12;
3145         hr = pUnk->vtbl->ITestOut (pUnk, &pTest);
3146         if (hr != 0)
3147                 return 13;
3148
3149         return 0;
3150 }
3151
3152 /*
3153  * mono_method_get_unmanaged_thunk tests
3154  */
3155
3156 #if defined(__GNUC__) && ((defined(__i386__) && (defined(__linux__) || defined (__APPLE__)) || defined (__FreeBSD__)) || (defined(__ppc__) && defined(__APPLE__)))
3157 #define ALIGN(size) __attribute__ ((aligned(size)))
3158 #else
3159 #define ALIGN(size)
3160 #endif
3161
3162
3163 /* thunks.cs:TestStruct */
3164 typedef struct _TestStruct {
3165         int A;
3166         double B ALIGN(8);  /* align according to  mono's struct layout */
3167 } TestStruct;
3168
3169 /* Searches for mono symbols in all loaded modules */
3170 static gpointer
3171 lookup_mono_symbol (const char *symbol_name)
3172 {
3173         gpointer symbol;
3174         if (g_module_symbol (g_module_open (NULL, G_MODULE_BIND_LAZY), symbol_name, &symbol))
3175                 return symbol;
3176         else
3177                 return NULL;
3178 }
3179
3180 /**
3181  * test_method_thunk:
3182  *
3183  * @test_id: the test number
3184  * @test_method_handle: MonoMethod* of the C# test method
3185  * @create_object_method_handle: MonoMethod* of thunks.cs:Test.CreateObject
3186  */
3187 LIBTEST_API int STDCALL  
3188 test_method_thunk (int test_id, gpointer test_method_handle, gpointer create_object_method_handle)
3189 {
3190         gpointer (*mono_method_get_unmanaged_thunk)(gpointer)
3191                 = lookup_mono_symbol ("mono_method_get_unmanaged_thunk");
3192
3193         gpointer (*mono_string_new_wrapper)(const char *)
3194                 = lookup_mono_symbol ("mono_string_new_wrapper");
3195
3196         char* (*mono_string_to_utf8)(gpointer)
3197                 = lookup_mono_symbol ("mono_string_to_utf8");
3198
3199         gpointer (*mono_object_unbox)(gpointer)
3200                 = lookup_mono_symbol ("mono_object_unbox");
3201
3202         gpointer test_method, ex = NULL;
3203         gpointer (STDCALL *CreateObject)(gpointer*);
3204
3205
3206         if (!mono_method_get_unmanaged_thunk)
3207                 return 1;
3208
3209         test_method =  mono_method_get_unmanaged_thunk (test_method_handle);
3210         if (!test_method)
3211                 return 2;
3212
3213         CreateObject = mono_method_get_unmanaged_thunk (create_object_method_handle);
3214         if (!CreateObject)
3215                 return 3;
3216
3217
3218         switch (test_id) {
3219
3220         case 0: {
3221                 /* thunks.cs:Test.Test0 */
3222                 void (STDCALL *F)(gpointer*) = test_method;
3223                 F (&ex);
3224                 break;
3225         }
3226
3227         case 1: {
3228                 /* thunks.cs:Test.Test1 */
3229                 int (STDCALL *F)(gpointer*) = test_method;
3230                 if (F (&ex) != 42)
3231                         return 4;
3232                 break;
3233         }
3234
3235         case 2: {
3236                 /* thunks.cs:Test.Test2 */
3237                 gpointer (STDCALL *F)(gpointer, gpointer*) = test_method;
3238                 gpointer str = mono_string_new_wrapper ("foo");
3239                 if (str != F (str, &ex))
3240                         return 4;
3241                 break;
3242         }
3243
3244         case 3: {
3245                 /* thunks.cs:Test.Test3 */
3246                 gpointer (STDCALL *F)(gpointer, gpointer, gpointer*);
3247                 gpointer obj;
3248                 gpointer str;
3249
3250                 F = test_method;
3251                 obj = CreateObject (&ex);
3252                 str = mono_string_new_wrapper ("bar");
3253
3254                 if (str != F (obj, str, &ex))
3255                         return 4;
3256                 break;
3257         }
3258
3259         case 4: {
3260                 /* thunks.cs:Test.Test4 */
3261                 int (STDCALL *F)(gpointer, gpointer, int, gpointer*);
3262                 gpointer obj;
3263                 gpointer str;
3264
3265                 F = test_method;
3266                 obj = CreateObject (&ex);
3267                 str = mono_string_new_wrapper ("bar");
3268
3269                 if (42 != F (obj, str, 42, &ex))
3270                         return 4;
3271
3272                 break;
3273         }
3274
3275         case 5: {
3276                 /* thunks.cs:Test.Test5 */
3277                 int (STDCALL *F)(gpointer, gpointer, int, gpointer*);
3278                 gpointer obj;
3279                 gpointer str;
3280
3281                 F = test_method;
3282                 obj = CreateObject (&ex);
3283                 str = mono_string_new_wrapper ("bar");
3284
3285                 F (obj, str, 42, &ex);
3286                 if (!ex)
3287                     return 4;
3288
3289                 break;
3290         }
3291
3292         case 6: {
3293                 /* thunks.cs:Test.Test6 */
3294                 int (STDCALL *F)(gpointer, guint8, gint16, gint32, gint64, float, double,
3295                                  gpointer, gpointer*);
3296                 gpointer obj;
3297                 gpointer str = mono_string_new_wrapper ("Test6");
3298                 int res;
3299
3300                 F = test_method;
3301                 obj = CreateObject (&ex);
3302
3303                 res = F (obj, 254, 32700, -245378, 6789600, 3.1415, 3.1415, str, &ex);
3304                 if (ex)
3305                         return 4;
3306
3307                 if (!res)
3308                         return 5;
3309
3310                 break;
3311         }
3312
3313         case 7: {
3314                 /* thunks.cs:Test.Test7 */
3315                 gint64 (STDCALL *F)(gpointer*) = test_method;
3316                 if (F (&ex) != G_MAXINT64)
3317                         return 4;
3318                 break;
3319         }
3320
3321         case 8: {
3322                 /* thunks.cs:Test.Test8 */
3323                 void (STDCALL *F)(guint8*, gint16*, gint32*, gint64*, float*, double*,
3324                                  gpointer*, gpointer*);
3325
3326                 guint8 a1;
3327                 gint16 a2;
3328                 gint32 a3;
3329                 gint64 a4;
3330                 float a5;
3331                 double a6;
3332                 gpointer a7;
3333
3334                 F = test_method;
3335
3336                 F (&a1, &a2, &a3, &a4, &a5, &a6, &a7, &ex);
3337                 if (ex)
3338                         return 4;
3339
3340                 if (!(a1 == 254 &&
3341                       a2 == 32700 &&
3342                       a3 == -245378 &&
3343                       a4 == 6789600 &&
3344                       (fabs (a5 - 3.1415) < 0.001) &&
3345                       (fabs (a6 - 3.1415) < 0.001) &&
3346                       strcmp (mono_string_to_utf8 (a7), "Test8") == 0))
3347                         return 5;
3348
3349                 break;
3350         }
3351
3352         case 9: {
3353                 /* thunks.cs:Test.Test9 */
3354                 void (STDCALL *F)(guint8*, gint16*, gint32*, gint64*, float*, double*,
3355                                  gpointer*, gpointer*);
3356
3357                 guint8 a1;
3358                 gint16 a2;
3359                 gint32 a3;
3360                 gint64 a4;
3361                 float a5;
3362                 double a6;
3363                 gpointer a7;
3364
3365                 F = test_method;
3366
3367                 F (&a1, &a2, &a3, &a4, &a5, &a6, &a7, &ex);
3368                 if (!ex)
3369                         return 4;
3370
3371                 break;
3372         }
3373
3374         case 10: {
3375                 /* thunks.cs:Test.Test10 */
3376                 void (STDCALL *F)(gpointer*, gpointer*);
3377
3378                 gpointer obj1, obj2;
3379
3380                 obj1 = obj2 = CreateObject (&ex);
3381                 if (ex)
3382                         return 4;
3383
3384                 F = test_method;
3385
3386                 F (&obj1, &ex);
3387                 if (ex)
3388                         return 5;
3389
3390                 if (obj1 == obj2)
3391                         return 6;
3392
3393                 break;
3394         }
3395
3396         case 100: {
3397                 /* thunks.cs:TestStruct.Test0 */
3398                 int (STDCALL *F)(gpointer*, gpointer*);
3399
3400                 gpointer obj;
3401                 TestStruct *a1;
3402                 int res;
3403
3404                 obj = CreateObject (&ex);
3405                 if (ex)
3406                         return 4;
3407
3408                 if (!obj)
3409                         return 5;
3410
3411                 a1 = mono_object_unbox (obj);
3412                 if (!a1)
3413                         return 6;
3414
3415                 a1->A = 42;
3416                 a1->B = 3.1415;
3417
3418                 F = test_method;
3419
3420                 res = F (obj, &ex);
3421                 if (ex)
3422                         return 7;
3423
3424                 if (!res)
3425                         return 8;
3426
3427                 /* check whether the call was really by value */
3428                 if (a1->A != 42 || a1->B != 3.1415)
3429                         return 9;
3430
3431                 break;
3432         }
3433
3434         case 101: {
3435                 /* thunks.cs:TestStruct.Test1 */
3436                 void (STDCALL *F)(gpointer, gpointer*);
3437
3438                 TestStruct *a1;
3439                 gpointer obj;
3440
3441                 obj = CreateObject (&ex);
3442                 if (ex)
3443                         return 4;
3444
3445                 if (!obj)
3446                         return 5;
3447
3448                 a1 = mono_object_unbox (obj);
3449                 if (!a1)
3450                         return 6;
3451
3452                 F = test_method;
3453
3454                 F (obj, &ex);
3455                 if (ex)
3456                         return 7;
3457
3458                 if (a1->A != 42)
3459                         return 8;
3460
3461                 if (!fabs (a1->B - 3.1415) < 0.001)
3462                         return 9;
3463
3464                 break;
3465         }
3466
3467         case 102: {
3468                 /* thunks.cs:TestStruct.Test2 */
3469                 gpointer (STDCALL *F)(gpointer*);
3470
3471                 TestStruct *a1;
3472                 gpointer obj;
3473
3474                 F = test_method;
3475
3476                 obj = F (&ex);
3477                 if (ex)
3478                         return 4;
3479
3480                 if (!obj)
3481                         return 5;
3482
3483                 a1 = mono_object_unbox (obj);
3484
3485                 if (a1->A != 42)
3486                         return 5;
3487
3488                 if (!fabs (a1->B - 3.1415) < 0.001)
3489                         return 6;
3490
3491                 break;
3492         }
3493
3494         case 103: {
3495                 /* thunks.cs:TestStruct.Test3 */
3496                 void (STDCALL *F)(gpointer, gpointer*);
3497
3498                 TestStruct *a1;
3499                 gpointer obj;
3500
3501                 obj = CreateObject (&ex);
3502                 if (ex)
3503                         return 4;
3504
3505                 if (!obj)
3506                         return 5;
3507                 
3508                 a1 = mono_object_unbox (obj);
3509
3510                 if (!a1)
3511                         return 6;
3512
3513                 a1->A = 42;
3514                 a1->B = 3.1415;
3515
3516                 F = test_method;
3517
3518                 F (obj, &ex);
3519                 if (ex)
3520                         return 4;
3521
3522                 if (a1->A != 1)
3523                         return 5;
3524
3525                 if (a1->B != 17)
3526                         return 6;
3527
3528                 break;
3529         }
3530
3531         default:
3532                 return 9;
3533
3534         }
3535
3536         return 0;
3537 }
3538
3539 typedef struct 
3540 {
3541         char a;
3542 } winx64_struct1;
3543
3544 LIBTEST_API int STDCALL  
3545 mono_test_Winx64_struct1_in (winx64_struct1 var)
3546 {
3547         if (var.a != 123)
3548                 return 1;
3549         return 0;
3550 }
3551
3552 typedef struct
3553 {
3554         char a;
3555         char b;
3556 } winx64_struct2;
3557
3558 LIBTEST_API int STDCALL  
3559 mono_test_Winx64_struct2_in (winx64_struct2 var)
3560 {
3561         if (var.a != 4)
3562                 return 1;
3563         if (var.b != 5)
3564                 return 2;
3565         return 0;
3566 }
3567
3568
3569 typedef struct
3570 {
3571         char a;
3572         char b;
3573         short c;
3574 } winx64_struct3;
3575
3576 LIBTEST_API int STDCALL  
3577 mono_test_Winx64_struct3_in (winx64_struct3 var)
3578 {
3579         if (var.a != 4)
3580                 return 1;
3581         if (var.b != 5)
3582                 return 2;
3583         if (var.c != 0x1234)
3584                 return 3;
3585         return 0;
3586 }
3587
3588 typedef struct
3589 {
3590         char a;
3591         char b;
3592         short c;
3593         unsigned int d;
3594 } winx64_struct4;
3595
3596 LIBTEST_API int STDCALL  
3597 mono_test_Winx64_struct4_in (winx64_struct4 var)
3598 {
3599         if (var.a != 4)
3600                 return 1;
3601         if (var.b != 5)
3602                 return 2;
3603         if (var.c != 0x1234)
3604                 return 3;
3605         if (var.d != 0x87654321)
3606                 return 4;
3607         return 0;
3608 }
3609
3610 typedef struct
3611 {
3612         char a;
3613         char b;
3614         char c;
3615 } winx64_struct5;
3616
3617 LIBTEST_API int STDCALL  
3618 mono_test_Winx64_struct5_in (winx64_struct5 var)
3619 {
3620         if (var.a != 4)
3621                 return 1;
3622         if (var.b != 5)
3623                 return 2;
3624         if (var.c != 6)
3625                 return 3;
3626         return 0;
3627 }
3628
3629 typedef struct
3630 {
3631         winx64_struct1 a;
3632         short b;
3633         char c;
3634 } winx64_struct6;
3635
3636 LIBTEST_API int STDCALL  
3637 mono_test_Winx64_struct6_in (winx64_struct6 var)
3638 {
3639         if (var.a.a != 4)
3640                 return 1;
3641         if (var.b != 5)
3642                 return 2;
3643         if (var.c != 6)
3644                 return 3;
3645         return 0;
3646 }
3647
3648 LIBTEST_API int STDCALL  
3649 mono_test_Winx64_structs_in1 (winx64_struct1 var1,
3650                          winx64_struct2 var2,
3651                          winx64_struct3 var3,
3652                          winx64_struct4 var4)
3653 {
3654         if (var1.a != 123)
3655                 return 1;
3656         
3657         if (var2.a != 4)
3658                 return 2;
3659         if (var2.b != 5)
3660                 return 3;
3661         
3662         if (var3.a != 4)
3663                 return 4;
3664         if (var3.b != 5)
3665                 return 2;
3666         if (var3.c != 0x1234)
3667                 return 5;
3668         
3669         if (var4.a != 4)
3670                 return 6;
3671         if (var4.b != 5)
3672                 return 7;
3673         if (var4.c != 0x1234)
3674                 return 8;
3675         if (var4.d != 0x87654321)
3676                 return 9;
3677         return 0;
3678 }
3679
3680 LIBTEST_API int STDCALL  
3681 mono_test_Winx64_structs_in2 (winx64_struct1 var1,
3682                          winx64_struct1 var2,
3683                          winx64_struct1 var3,
3684                          winx64_struct1 var4,
3685                          winx64_struct1 var5)
3686 {
3687         if (var1.a != 1)
3688                 return 1;
3689         if (var2.a != 2)
3690                 return 2;
3691         if (var3.a != 3)
3692                 return 3;
3693         if (var4.a != 4)
3694                 return 4;
3695         if (var5.a != 5)
3696                 return 5;
3697         
3698         return 0;
3699 }
3700
3701 LIBTEST_API int STDCALL  
3702 mono_test_Winx64_structs_in3 (winx64_struct1 var1,
3703                          winx64_struct5 var2,
3704                          winx64_struct1 var3,
3705                          winx64_struct5 var4,
3706                          winx64_struct1 var5,
3707                          winx64_struct5 var6)
3708 {
3709         if (var1.a != 1)
3710                 return 1;
3711         
3712         if (var2.a != 2)
3713                 return 2;
3714         if (var2.b != 3)
3715                 return 2;
3716         if (var2.c != 4)
3717                 return 4;
3718         
3719         if (var3.a != 5)
3720                 return 5;
3721         
3722         if (var4.a != 6)
3723                 return 6;
3724         if (var4.b != 7)
3725                 return 7;
3726         if (var4.c != 8)
3727                 return 8;
3728         
3729         if (var5.a != 9)
3730                 return 9;
3731
3732         if (var6.a != 10)
3733                 return 10;
3734         if (var6.b != 11)
3735                 return 11;
3736         if (var6.c != 12)
3737                 return 12;
3738         
3739         return 0;
3740 }
3741
3742 LIBTEST_API winx64_struct1 STDCALL  
3743 mono_test_Winx64_struct1_ret (void)
3744 {
3745         winx64_struct1 ret;
3746         ret.a = 123;
3747         return ret;
3748 }
3749
3750 LIBTEST_API winx64_struct2 STDCALL  
3751 mono_test_Winx64_struct2_ret (void)
3752 {
3753         winx64_struct2 ret;
3754         ret.a = 4;
3755         ret.b = 5;
3756         return ret;
3757 }
3758
3759 LIBTEST_API winx64_struct3 STDCALL  
3760 mono_test_Winx64_struct3_ret (void)
3761 {
3762         winx64_struct3 ret;
3763         ret.a = 4;
3764         ret.b = 5;
3765         ret.c = 0x1234;
3766         return ret;
3767 }
3768
3769 LIBTEST_API winx64_struct4 STDCALL  
3770 mono_test_Winx64_struct4_ret (void)
3771 {
3772         winx64_struct4 ret;
3773         ret.a = 4;
3774         ret.b = 5;
3775         ret.c = 0x1234;
3776         ret.d = 0x87654321;
3777         return ret;
3778 }
3779
3780 LIBTEST_API winx64_struct5 STDCALL  
3781 mono_test_Winx64_struct5_ret (void)
3782 {
3783         winx64_struct5 ret;
3784         ret.a = 4;
3785         ret.b = 5;
3786         ret.c = 6;
3787         return ret;
3788 }
3789
3790 LIBTEST_API winx64_struct1 STDCALL  
3791 mono_test_Winx64_struct1_ret_5_args (char a, char b, char c, char d, char e)
3792 {
3793         winx64_struct1 ret;
3794         ret.a = a + b + c + d + e;
3795         return ret;
3796 }
3797
3798 LIBTEST_API winx64_struct5 STDCALL
3799 mono_test_Winx64_struct5_ret6_args (char a, char b, char c, char d, char e)
3800 {
3801         winx64_struct5 ret;
3802         ret.a = a + b;
3803         ret.b = c + d;
3804         ret.c = e;
3805         return ret;
3806 }
3807
3808 typedef struct
3809 {
3810         float a;
3811         float b;
3812 } winx64_floatStruct;
3813
3814 LIBTEST_API int STDCALL  
3815 mono_test_Winx64_floatStruct (winx64_floatStruct a)
3816 {
3817         if (a.a > 5.6 || a.a < 5.4)
3818                 return 1;
3819
3820         if (a.b > 9.6 || a.b < 9.4)
3821                 return 2;
3822         
3823         return 0;
3824 }
3825
3826 typedef struct
3827 {
3828         double a;
3829 } winx64_doubleStruct;
3830
3831 LIBTEST_API int STDCALL  
3832 mono_test_Winx64_doubleStruct (winx64_doubleStruct a)
3833 {
3834         if (a.a > 5.6 || a.a < 5.4)
3835                 return 1;
3836         
3837         return 0;
3838 }
3839
3840 typedef int (STDCALL *managed_struct1_delegate) (winx64_struct1 a);
3841
3842 LIBTEST_API int STDCALL 
3843 mono_test_managed_Winx64_struct1_in(managed_struct1_delegate func)
3844 {
3845         winx64_struct1 val;
3846         val.a = 5;
3847         return func (val);
3848 }
3849
3850 typedef int (STDCALL *managed_struct5_delegate) (winx64_struct5 a);
3851
3852 LIBTEST_API int STDCALL 
3853 mono_test_managed_Winx64_struct5_in(managed_struct5_delegate func)
3854 {
3855         winx64_struct5 val;
3856         val.a = 5;
3857         val.b = 0x10;
3858         val.c = 0x99;
3859         return func (val);
3860 }
3861
3862 typedef int (STDCALL *managed_struct1_struct5_delegate) (winx64_struct1 a, winx64_struct5 b,
3863                                                          winx64_struct1 c, winx64_struct5 d,
3864                                                          winx64_struct1 e, winx64_struct5 f);
3865
3866 LIBTEST_API int STDCALL 
3867 mono_test_managed_Winx64_struct1_struct5_in(managed_struct1_struct5_delegate func)
3868 {
3869         winx64_struct1 a, c, e;
3870         winx64_struct5 b, d, f;
3871         a.a = 1;
3872         b.a = 2; b.b = 3; b.c = 4;
3873         c.a = 5;
3874         d.a = 6; d.b = 7; d.c = 8;
3875         e.a = 9;
3876         f.a = 10; f.b = 11; f.c = 12;
3877
3878         return func (a, b, c, d, e, f);
3879 }
3880
3881 typedef winx64_struct1 (STDCALL *managed_struct1_ret_delegate) (void);
3882
3883 LIBTEST_API int STDCALL 
3884 mono_test_Winx64_struct1_ret_managed (managed_struct1_ret_delegate func)
3885 {
3886         winx64_struct1 ret;
3887
3888         ret = func ();
3889
3890         if (ret.a != 0x45)
3891                 return 1;
3892         
3893         return 0;
3894 }
3895
3896 typedef winx64_struct5 (STDCALL *managed_struct5_ret_delegate) (void);
3897
3898 LIBTEST_API int STDCALL 
3899 mono_test_Winx64_struct5_ret_managed (managed_struct5_ret_delegate func)
3900 {
3901         winx64_struct5 ret;
3902
3903         ret = func ();
3904
3905         if (ret.a != 0x12)
3906                 return 1;
3907         if (ret.b != 0x34)
3908                 return 2;
3909         if (ret.c != 0x56)
3910                 return 3;
3911         
3912         return 0;
3913 }
3914
3915 LIBTEST_API int STDCALL 
3916 mono_test_marshal_bool_in (int arg, unsigned int expected, unsigned int bDefaultMarsh, unsigned int bBoolCustMarsh,
3917                            char bI1CustMarsh, unsigned char bU1CustMarsh, unsigned short bVBCustMarsh)
3918 {
3919         switch (arg) {
3920         case 1: 
3921                 if (bDefaultMarsh != expected)
3922                         return 1;
3923                 break;
3924         case 2: 
3925                 if (bBoolCustMarsh != expected)
3926                         return 2;
3927                 break;
3928         case 3: 
3929                 if (bI1CustMarsh != expected)
3930                         return 3;
3931                 break;
3932         case 4: 
3933                 if (bU1CustMarsh != expected)
3934                         return 4;
3935                 break;
3936         case 5: 
3937                 if (bVBCustMarsh != expected)
3938                         return 5;
3939                 break;
3940         default:
3941                 return 999;             
3942         }
3943         return 0;
3944 }
3945
3946 LIBTEST_API int STDCALL 
3947 mono_test_marshal_bool_out (int arg, unsigned int testVal, unsigned int* bDefaultMarsh, unsigned int* bBoolCustMarsh,
3948                            char* bI1CustMarsh, unsigned char* bU1CustMarsh, unsigned short* bVBCustMarsh)
3949 {
3950         switch (arg) {
3951         case 1: 
3952                 if (!bDefaultMarsh)
3953                         return 1;
3954                 *bDefaultMarsh = testVal;
3955                 break;  
3956         case 2: 
3957                 if (!bBoolCustMarsh)
3958                         return 2;
3959                 *bBoolCustMarsh = testVal;
3960                 break;  
3961         case 3: 
3962                 if (!bI1CustMarsh)
3963                         return 3;
3964                 *bI1CustMarsh = (char)testVal;
3965                 break;  
3966         case 4: 
3967                 if (!bU1CustMarsh)
3968                         return 4;
3969                 *bU1CustMarsh = (unsigned char)testVal;
3970                 break;  
3971         case 5: 
3972                 if (!bVBCustMarsh)
3973                         return 5;
3974                 *bVBCustMarsh = (unsigned short)testVal;
3975                 break;  
3976         default:
3977                 return 999;
3978         }
3979         return 0;
3980 }
3981
3982 LIBTEST_API int STDCALL 
3983 mono_test_marshal_bool_ref (int arg, unsigned int expected, unsigned int testVal, unsigned int* bDefaultMarsh,
3984                             unsigned int* bBoolCustMarsh, char* bI1CustMarsh, unsigned char* bU1CustMarsh, 
3985                             unsigned short* bVBCustMarsh)
3986 {
3987         switch (arg) {
3988         case 1: 
3989                 if (!bDefaultMarsh)
3990                         return 1;
3991                 if (*bDefaultMarsh != expected)
3992                         return 2;
3993                 *bDefaultMarsh = testVal;
3994                 break;
3995         case 2: 
3996                 if (!bBoolCustMarsh)
3997                         return 3;
3998                 if (*bBoolCustMarsh != expected)
3999                         return 4;
4000                 *bBoolCustMarsh = testVal;
4001                 break;
4002         case 3: 
4003                 if (!bI1CustMarsh)
4004                         return 5;
4005                 if (*bI1CustMarsh != expected)
4006                         return 6;
4007                 *bI1CustMarsh = (char)testVal;
4008                 break;
4009         case 4: 
4010                 if (!bU1CustMarsh)
4011                         return 7;
4012                 if (*bU1CustMarsh != expected)
4013                         return 8;
4014                 *bU1CustMarsh = (unsigned char)testVal;
4015                 break;
4016         case 5: 
4017                 if (!bVBCustMarsh)
4018                         return 9;
4019                 if (*bVBCustMarsh != expected)
4020                         return 10;
4021                 *bVBCustMarsh = (unsigned short)testVal;
4022                 break;
4023         default:
4024                 return 999;             
4025         }
4026         return 0;
4027 }
4028
4029
4030 typedef int (STDCALL *MarshalBoolInDelegate) (int arg, unsigned int expected, unsigned int bDefaultMarsh,
4031         unsigned int bBoolCustMarsh, char bI1CustMarsh, unsigned char bU1CustMarsh, unsigned short bVBCustMarsh);
4032
4033 LIBTEST_API int STDCALL 
4034 mono_test_managed_marshal_bool_in (int arg, unsigned int expected, unsigned int testVal, MarshalBoolInDelegate pfcn)
4035 {
4036         if (!pfcn)
4037                 return 0x9900;
4038
4039         switch (arg) {
4040         case 1:
4041                 return pfcn (arg, expected, testVal, 0, 0, 0, 0);
4042         case 2:
4043                 return pfcn (arg, expected, 0, testVal,  0, 0, 0);
4044         case 3:
4045                 return pfcn (arg, expected, 0, 0, testVal, 0, 0);
4046         case 4:
4047                 return pfcn (arg, expected, 0, 0, 0, testVal, 0);
4048         case 5:
4049                 return pfcn (arg, expected, 0, 0, 0, 0, testVal);
4050         default:
4051                 return 0x9800;
4052         }
4053
4054         return 0;
4055 }
4056
4057 typedef int (STDCALL *MarshalBoolOutDelegate) (int arg, unsigned int expected, unsigned int* bDefaultMarsh,
4058         unsigned int* bBoolCustMarsh, char* bI1CustMarsh, unsigned char* bU1CustMarsh, unsigned short* bVBCustMarsh);
4059
4060 LIBTEST_API int STDCALL 
4061 mono_test_managed_marshal_bool_out (int arg, unsigned int expected, unsigned int testVal, MarshalBoolOutDelegate pfcn)
4062 {
4063         int ret;
4064         unsigned int lDefaultMarsh, lBoolCustMarsh;
4065         char lI1CustMarsh = 0;
4066         unsigned char lU1CustMarsh = 0;
4067         unsigned short lVBCustMarsh = 0;
4068         lDefaultMarsh = lBoolCustMarsh = 0;
4069
4070         if (!pfcn)
4071                 return 0x9900;
4072
4073         switch (arg) {
4074         case 1: {
4075                 unsigned int ltVal = 0;
4076                 ret = pfcn (arg, testVal, &ltVal, &lBoolCustMarsh, &lI1CustMarsh, &lU1CustMarsh, &lVBCustMarsh);
4077                 if (ret)
4078                         return 0x0100 + ret;
4079                 if (expected != ltVal)
4080                         return 0x0200;
4081                 break;
4082         }
4083         case 2: {
4084                 unsigned int ltVal = 0;
4085                 ret = pfcn (arg, testVal, &lDefaultMarsh, &ltVal, &lI1CustMarsh, &lU1CustMarsh, &lVBCustMarsh);
4086                 if (ret)
4087                         return 0x0300 + ret;
4088                 if (expected != ltVal)
4089                         return 0x0400;
4090                 break;
4091         }
4092         case 3: {
4093                 char ltVal = 0;
4094                 ret = pfcn (arg, testVal, &lDefaultMarsh, &lBoolCustMarsh, &ltVal, &lU1CustMarsh, &lVBCustMarsh);
4095                 if (ret)
4096                         return 0x0500 + ret;
4097                 if (expected != ltVal)
4098                         return 0x0600;
4099                 break;
4100         }
4101         case 4: {
4102                 unsigned char ltVal = 0;
4103                 ret = pfcn (arg, testVal, &lDefaultMarsh, &lBoolCustMarsh, &lI1CustMarsh, &ltVal, &lVBCustMarsh);
4104                 if (ret)
4105                         return 0x0700 + ret;
4106                 if (expected != ltVal)
4107                         return 0x0800;
4108                 break;
4109         }
4110         case 5: {
4111                 unsigned short ltVal = 0;
4112                 ret = pfcn (arg, testVal, &lDefaultMarsh, &lBoolCustMarsh, &lI1CustMarsh, &lU1CustMarsh, &ltVal);
4113                 if (ret)
4114                         return 0x0900 + ret;
4115                 if (expected != ltVal)
4116                         return 0x1000;
4117                 break;
4118         }
4119         default:
4120                 return 0x9800;
4121         }
4122
4123         return 0;
4124 }
4125
4126 typedef int (STDCALL *MarshalBoolRefDelegate) (int arg, unsigned int expected, unsigned int testVal, unsigned int* bDefaultMarsh,
4127         unsigned int* bBoolCustMarsh, char* bI1CustMarsh, unsigned char* bU1CustMarsh, unsigned short* bVBCustMarsh);
4128
4129 LIBTEST_API int STDCALL 
4130 mono_test_managed_marshal_bool_ref (int arg, unsigned int expected, unsigned int testVal, unsigned int outExpected,
4131                                     unsigned int outTestVal, MarshalBoolRefDelegate pfcn)
4132 {
4133         int ret;
4134         unsigned int lDefaultMarsh, lBoolCustMarsh;
4135         char lI1CustMarsh = 0;
4136         unsigned char lU1CustMarsh = 0;
4137         unsigned short lVBCustMarsh = 0;
4138         lDefaultMarsh = lBoolCustMarsh = 0;
4139
4140         if (!pfcn)
4141                 return 0x9900;
4142
4143         switch (arg) {
4144         case 1:
4145         {
4146                 unsigned int ltestVal = testVal;
4147                 ret = pfcn (arg, expected, outTestVal, &ltestVal, &lBoolCustMarsh, &lI1CustMarsh, &lU1CustMarsh, &lVBCustMarsh);
4148                 if (ret)
4149                         return 0x0100 + ret;
4150                 if (outExpected != ltestVal)
4151                         return 0x0200;
4152                 break;
4153         }
4154         case 2:
4155         {
4156                 unsigned int ltestVal = testVal;
4157                 ret = pfcn (arg, expected, outTestVal, &lDefaultMarsh, &ltestVal, &lI1CustMarsh, &lU1CustMarsh, &lVBCustMarsh);
4158                 if (ret)
4159                         return 0x0300 + ret;
4160                 if (outExpected != ltestVal)
4161                         return 0x0400;
4162                 break;
4163         }
4164         case 3:
4165         {
4166                 char ltestVal = testVal;
4167                 ret = pfcn (arg, expected, outTestVal, &lDefaultMarsh, &lBoolCustMarsh, &ltestVal, &lU1CustMarsh, &lVBCustMarsh);
4168                 if (ret)
4169                         return 0x0500 + ret;
4170                 if (outExpected != ltestVal)
4171                         return 0x0600;
4172                 break;
4173         }
4174         case 4:
4175         {
4176                 unsigned char ltestVal = testVal;
4177                 ret = pfcn (arg, expected, outTestVal, &lDefaultMarsh, &lBoolCustMarsh, &lI1CustMarsh, &ltestVal, &lVBCustMarsh);
4178                 if (ret)
4179                         return 0x0700 + ret;
4180                 if (outExpected != ltestVal)
4181                         return 0x0800;
4182                 break;
4183         }
4184         case 5:
4185         {
4186                 unsigned short ltestVal = testVal;
4187                 ret = pfcn (arg, expected, outTestVal, &lDefaultMarsh, &lBoolCustMarsh, &lI1CustMarsh, &lU1CustMarsh, &ltestVal);
4188                 if (ret)
4189                         return 0x0900 + ret;
4190                 if (outExpected != ltestVal)
4191                         return 0x1000;
4192                 break;
4193         }
4194         default:
4195                 return 0x9800;
4196         }
4197
4198         return 0;
4199 }
4200
4201 #ifdef WIN32
4202
4203 LIBTEST_API int STDCALL 
4204 mono_test_marshal_variant_out_safearray_1dim_vt_bstr_empty (SAFEARRAY** safearray)
4205 {
4206         /* Create an empty one-dimensional array of variants */
4207         SAFEARRAY *pSA;
4208         SAFEARRAYBOUND dimensions [1];
4209
4210         dimensions [0].lLbound = 0;
4211         dimensions [0].cElements = 0;
4212
4213         pSA= SafeArrayCreate (VT_VARIANT, 1, dimensions);
4214         *safearray = pSA;
4215         return S_OK;
4216 }
4217
4218 LIBTEST_API int STDCALL 
4219 mono_test_marshal_variant_out_safearray_1dim_vt_bstr (SAFEARRAY** safearray)
4220 {
4221         /* Create a one-dimensional array of 10 variants filled with "0" to "9" */
4222         SAFEARRAY *pSA;
4223         SAFEARRAYBOUND dimensions [1];
4224         long i;
4225         gchar buffer [20];
4226         HRESULT hr = S_OK;
4227         long indices [1];
4228
4229         dimensions [0].lLbound = 0;
4230         dimensions [0].cElements = 10;
4231
4232         pSA= SafeArrayCreate (VT_VARIANT, 1, dimensions);
4233         for (i= dimensions [0].lLbound; i< (dimensions [0].cElements + dimensions [0].lLbound); i++) {
4234                 VARIANT vOut;
4235                 VariantInit (&vOut);
4236                 vOut.vt = VT_BSTR;
4237                 _ltoa (i,buffer,10);
4238                 vOut.bstrVal= marshal_bstr_alloc (buffer);
4239                 indices [0] = i;
4240                 if ((hr = SafeArrayPutElement (pSA, indices, &vOut)) != S_OK) {
4241                         VariantClear (&vOut);
4242                         SafeArrayDestroy (pSA);
4243                         return hr;
4244                 }
4245                 VariantClear (&vOut);
4246         }
4247         *safearray = pSA;
4248         return hr;
4249 }
4250
4251 LIBTEST_API int STDCALL 
4252 mono_test_marshal_variant_out_safearray_2dim_vt_int (SAFEARRAY** safearray)
4253 {
4254         /* Create a two-dimensional array of 4x3 variants filled with 11, 12, 13, etc. */
4255         SAFEARRAY *pSA;
4256         SAFEARRAYBOUND dimensions [2];
4257         long i, j;
4258         HRESULT hr = S_OK;
4259         long indices [2];
4260
4261         dimensions [0].lLbound = 0;
4262         dimensions [0].cElements = 4;
4263         dimensions [1].lLbound = 0;
4264         dimensions [1].cElements = 3;
4265
4266         pSA= SafeArrayCreate(VT_VARIANT, 2, dimensions);
4267         for (i= dimensions [0].lLbound; i< (dimensions [0].cElements + dimensions [0].lLbound); i++) {
4268                 for (j= dimensions [1].lLbound; j< (dimensions [1].cElements + dimensions [1].lLbound); j++) {
4269                         VARIANT vOut;
4270                         VariantInit (&vOut);
4271                         vOut.vt = VT_I4;
4272                         vOut.intVal = (i+1)*10+(j+1);
4273                         indices [0] = i;
4274                         indices [1] = j;
4275                         if ((hr = SafeArrayPutElement (pSA, indices, &vOut)) != S_OK) {
4276                                 VariantClear (&vOut);
4277                                 SafeArrayDestroy (pSA);
4278                                 return hr;
4279                         }
4280                         VariantClear (&vOut);  // does a deep destroy of source VARIANT 
4281                 }
4282         }
4283         *safearray = pSA;
4284         return hr;
4285 }
4286
4287 LIBTEST_API int STDCALL 
4288 mono_test_marshal_variant_out_safearray_4dim_vt_int (SAFEARRAY** safearray)
4289 {
4290         /* Create a four-dimensional array of 10x3x6x7 variants filled with their indices */
4291         /* Also use non zero lower bounds                                                 */
4292         SAFEARRAY *pSA;
4293         SAFEARRAYBOUND dimensions [4];
4294         long i;
4295         HRESULT hr = S_OK;
4296         VARIANT *pData;
4297
4298         dimensions [0].lLbound = 15;
4299         dimensions [0].cElements = 10;
4300         dimensions [1].lLbound = 20;
4301         dimensions [1].cElements = 3;
4302         dimensions [2].lLbound = 5;
4303         dimensions [2].cElements = 6;
4304         dimensions [3].lLbound = 12;
4305         dimensions [3].cElements = 7;
4306
4307         pSA= SafeArrayCreate (VT_VARIANT, 4, dimensions);
4308
4309         SafeArrayAccessData (pSA, (void **)&pData);
4310
4311         for (i= 0; i< 10*3*6*7; i++) {
4312                 VariantInit(&pData [i]);
4313                 pData [i].vt = VT_I4;
4314                 pData [i].intVal = i;
4315         }
4316         SafeArrayUnaccessData(pSA);
4317         *safearray = pSA;
4318         return hr;
4319 }
4320
4321 #endif
4322
4323