2009-09-30 Zoltan Varga <vargaz@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 (void)
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 LIBTEST_API void STDCALL
1000 mono_test_marshal_stringbuilder_out (char **s)
1001 {
1002         const char m[] = "This is my message.  Isn't it nice?";
1003         char *str;
1004
1005         str = g_malloc (strlen (m) + 1);
1006         memcpy (str, m, strlen (m) + 1);
1007         
1008         *s = str;
1009 }
1010
1011 LIBTEST_API int STDCALL  
1012 mono_test_marshal_stringbuilder_out_unicode (gunichar2 **s)
1013 {
1014         const char m[] = "This is my message.  Isn't it nice?";
1015         gunichar2 *s2;
1016         glong len;
1017
1018         s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
1019         
1020         len = (len * 2) + 2;
1021         *s = g_malloc (len);
1022         memcpy (*s, s2, len);
1023
1024         g_free (s2);
1025
1026         return 0;
1027 }
1028
1029 typedef struct {
1030 #ifndef __GNUC__
1031     char a;
1032 #endif
1033 } EmptyStruct;
1034
1035 LIBTEST_API int STDCALL 
1036 mono_test_marshal_empty_string_array (char **array)
1037 {
1038         return (array == NULL) ? 0 : 1;
1039 }
1040
1041 LIBTEST_API int STDCALL 
1042 mono_test_marshal_string_array (char **array)
1043 {
1044         if (strcmp (array [0], "ABC"))
1045                 return 1;
1046         if (strcmp (array [1], "DEF"))
1047                 return 2;
1048
1049         if (array [2] != NULL)
1050                 return 3;
1051
1052         return 0;
1053 }
1054
1055 LIBTEST_API int STDCALL 
1056 mono_test_marshal_byref_string_array (char ***array)
1057 {
1058         if (*array == NULL)
1059                 return 0;
1060
1061         if (strcmp ((*array) [0], "Alpha"))
1062                 return 2;
1063         if (strcmp ((*array) [1], "Beta"))
1064                 return 2;
1065         if (strcmp ((*array) [2], "Gamma"))
1066                 return 2;
1067
1068         return 1;
1069 }
1070
1071 LIBTEST_API int STDCALL 
1072 mono_test_marshal_stringbuilder_array (char **array)
1073 {
1074         if (strcmp (array [0], "ABC"))
1075                 return 1;
1076         if (strcmp (array [1], "DEF"))
1077                 return 2;
1078
1079         strcpy (array [0], "DEF");
1080         strcpy (array [1], "ABC");
1081
1082         return 0;
1083 }
1084
1085 LIBTEST_API int STDCALL 
1086 mono_test_marshal_unicode_string_array (gunichar2 **array, char **array2)
1087 {
1088         GError *error = NULL;
1089         char *s;
1090         
1091         s = g_utf16_to_utf8 (array [0], -1, NULL, NULL, &error);
1092         if (strcmp (s, "ABC")) {
1093                 g_free (s);
1094                 return 1;
1095         }
1096         else
1097                 g_free (s);
1098
1099         s = g_utf16_to_utf8 (array [1], -1, NULL, NULL, &error);
1100         if (strcmp (s, "DEF")) {
1101                 g_free (s);
1102                 return 2;
1103         }
1104         else
1105                 g_free (s);
1106
1107         if (strcmp (array2 [0], "ABC"))
1108                 return 3;
1109
1110         if (strcmp (array2 [1], "DEF")) 
1111                 return 4;
1112
1113         return 0;
1114 }
1115
1116 /* this does not work on Redhat gcc 2.96 */
1117 LIBTEST_API int STDCALL  
1118 mono_test_empty_struct (int a, EmptyStruct es, int b)
1119 {
1120         // printf ("mono_test_empty_struct %d %d\n", a, b);
1121
1122         // Intel icc on ia64 passes 'es' in 2 registers
1123 #if defined(__ia64) && defined(__INTEL_COMPILER)
1124         return 0;
1125 #else
1126         if (a == 1 && b == 2)
1127                 return 0;
1128         return 1;
1129 #endif
1130 }
1131
1132 typedef struct {
1133        char a[100];
1134 } ByValStrStruct;
1135
1136 LIBTEST_API ByValStrStruct * STDCALL 
1137 mono_test_byvalstr_gen (void)
1138 {
1139         ByValStrStruct *ret;
1140        
1141         ret = malloc(sizeof(ByValStrStruct));
1142         memset(ret, 'a', sizeof(ByValStrStruct)-1);
1143         ret->a[sizeof(ByValStrStruct)-1] = 0;
1144
1145         return ret;
1146 }
1147
1148 LIBTEST_API int STDCALL 
1149 mono_test_byvalstr_check (ByValStrStruct* data, char* correctString)
1150 {
1151         int ret;
1152
1153         ret = strcmp(data->a, correctString);
1154         // printf ("T1: %s\n", data->a);
1155         // printf ("T2: %s\n", correctString);
1156
1157         marshal_free (data);
1158         return (ret != 0);
1159 }
1160
1161 typedef struct {
1162         guint16 a[4];
1163         int  flag;
1164 } ByValStrStruct_Unicode;
1165
1166 LIBTEST_API int STDCALL 
1167 mono_test_byvalstr_check_unicode (ByValStrStruct_Unicode *ref, int test)
1168 {
1169         if (ref->flag != 0x1234abcd){
1170                 printf ("overwritten data");
1171                 return 1;
1172         }
1173             
1174         if (test == 1 || test == 3){
1175                 if (ref->a [0] != '1' ||
1176                     ref->a [1] != '2'   ||
1177                     ref->a [2] != '3')
1178                         return 1;
1179                 return 0;
1180         }
1181         if (test == 2){
1182                 if (ref->a [0] != '1' ||
1183                     ref->a [1] != '2')
1184                         return 1;
1185                 return 0;
1186         }
1187         return 10;
1188 }
1189
1190 LIBTEST_API int STDCALL 
1191 NameManglingAnsi (char *data)
1192 {
1193         return data [0] + data [1] + data [2];
1194 }
1195
1196 LIBTEST_API int STDCALL 
1197 NameManglingAnsiA (char *data)
1198 {
1199         g_assert_not_reached ();
1200 }
1201
1202 LIBTEST_API int STDCALL 
1203 NameManglingAnsiW (char *data)
1204 {
1205         g_assert_not_reached ();
1206 }
1207
1208 LIBTEST_API int STDCALL 
1209 NameManglingAnsi2A (char *data)
1210 {
1211         return data [0] + data [1] + data [2];
1212 }
1213
1214 LIBTEST_API int STDCALL 
1215 NameManglingAnsi2W (char *data)
1216 {
1217         g_assert_not_reached ();
1218 }
1219
1220 LIBTEST_API int STDCALL 
1221 NameManglingUnicode (char *data)
1222 {
1223         g_assert_not_reached ();
1224 }
1225
1226 LIBTEST_API int STDCALL 
1227 NameManglingUnicodeW (gunichar2 *data)
1228 {
1229         return data [0] + data [1] + data [2];
1230 }
1231
1232 LIBTEST_API int STDCALL 
1233 NameManglingUnicode2 (gunichar2 *data)
1234 {
1235         return data [0] + data [1] + data [2];
1236 }
1237
1238 LIBTEST_API int STDCALL 
1239 NameManglingAutoW (char *data)
1240 {
1241 #ifdef WIN32
1242         return (data [0] + data [1] + data [2]) == 131 ? 0 : 1;
1243 #else
1244         g_assert_not_reached ();
1245 #endif
1246 }
1247
1248 LIBTEST_API int STDCALL 
1249 NameManglingAuto (char *data)
1250 {
1251 #ifndef WIN32
1252         return (data [0] + data [1] + data [2]) == 198 ? 0 : 1;
1253 #else
1254         g_assert_not_reached ();
1255 #endif
1256 }
1257
1258 typedef int (STDCALL *intcharFunc)(const char*);
1259
1260 LIBTEST_API void STDCALL 
1261 callFunction (intcharFunc f)
1262 {
1263         f ("ABC");
1264 }
1265
1266 typedef struct {
1267         const char* str;
1268         int i;
1269 } SimpleObj;
1270
1271 LIBTEST_API int STDCALL 
1272 class_marshal_test0 (SimpleObj *obj1)
1273 {
1274         // printf ("class_marshal_test0 %s %d\n", obj1->str, obj1->i);
1275
1276         if (strcmp(obj1->str, "T1"))
1277                 return -1;
1278         if (obj1->i != 4)
1279                 return -2;
1280
1281         return 0;
1282 }
1283
1284 LIBTEST_API int STDCALL 
1285 class_marshal_test4 (SimpleObj *obj1)
1286 {
1287         if (obj1)
1288                 return -1;
1289
1290         return 0;
1291 }
1292
1293 LIBTEST_API void STDCALL
1294 class_marshal_test1 (SimpleObj **obj1)
1295 {
1296         SimpleObj *res = malloc (sizeof (SimpleObj));
1297
1298         res->str = g_strdup ("ABC");
1299         res->i = 5;
1300
1301         *obj1 = res;
1302 }
1303
1304 LIBTEST_API int STDCALL 
1305 class_marshal_test2 (SimpleObj **obj1)
1306 {
1307         // printf ("class_marshal_test2 %s %d\n", (*obj1)->str, (*obj1)->i);
1308
1309         if (strcmp((*obj1)->str, "ABC"))
1310                 return -1;
1311         if ((*obj1)->i != 5)
1312                 return -2;
1313
1314         return 0;
1315 }
1316
1317 LIBTEST_API int STDCALL 
1318 string_marshal_test0 (char *str)
1319 {
1320         if (strcmp (str, "TEST0"))
1321                 return -1;
1322
1323         return 0;
1324 }
1325
1326 LIBTEST_API void STDCALL
1327 string_marshal_test1 (const char **str)
1328 {
1329         *str = g_strdup ("TEST1");
1330 }
1331
1332 LIBTEST_API int STDCALL 
1333 string_marshal_test2 (char **str)
1334 {
1335         // printf ("string_marshal_test2 %s\n", *str);
1336
1337         if (strcmp (*str, "TEST1"))
1338                 return -1;
1339
1340         return 0;
1341 }
1342
1343 LIBTEST_API int STDCALL 
1344 string_marshal_test3 (char *str)
1345 {
1346         if (str)
1347                 return -1;
1348
1349         return 0;
1350 }
1351
1352 typedef struct {
1353         int a;
1354         int b;
1355 } BlittableClass;
1356
1357 LIBTEST_API BlittableClass* STDCALL 
1358 TestBlittableClass (BlittableClass *vl)
1359 {
1360         BlittableClass *res;
1361
1362         // printf ("TestBlittableClass %d %d\n", vl->a, vl->b);
1363
1364         if (vl) {
1365                 vl->a++;
1366                 vl->b++;
1367
1368                 res = g_new0 (BlittableClass, 1);
1369                 memcpy (res, vl, sizeof (BlittableClass));
1370         } else {
1371                 res = g_new0 (BlittableClass, 1);
1372                 res->a = 42;
1373                 res->b = 43;
1374         }
1375
1376         return res;
1377 }
1378
1379 typedef struct OSVERSIONINFO_STRUCT
1380
1381         int a; 
1382         int b; 
1383 } OSVERSIONINFO_STRUCT;
1384
1385 LIBTEST_API int STDCALL  
1386 MyGetVersionEx (OSVERSIONINFO_STRUCT *osvi)
1387 {
1388
1389         // printf ("GOT %d %d\n", osvi->a, osvi->b);
1390
1391         osvi->a += 1;
1392         osvi->b += 1;
1393
1394         return osvi->a + osvi->b;
1395 }
1396
1397 LIBTEST_API int STDCALL  
1398 BugGetVersionEx (int a, int b, int c, int d, int e, int f, int g, int h, OSVERSIONINFO_STRUCT *osvi)
1399 {
1400
1401         // printf ("GOT %d %d\n", osvi->a, osvi->b);
1402
1403         osvi->a += 1;
1404         osvi->b += 1;
1405
1406         return osvi->a + osvi->b;
1407 }
1408
1409 LIBTEST_API int STDCALL 
1410 mono_test_marshal_point (point pt)
1411 {
1412         // printf("point %g %g\n", pt.x, pt.y);
1413         if (pt.x == 1.25 && pt.y == 3.5)
1414                 return 0;
1415
1416         return 1;
1417 }
1418
1419 typedef struct {
1420         int x;
1421         double y;
1422 } mixed_point;
1423
1424 LIBTEST_API int STDCALL 
1425 mono_test_marshal_mixed_point (mixed_point pt)
1426 {
1427         // printf("mixed point %d %g\n", pt.x, pt.y);
1428         if (pt.x == 5 && pt.y == 6.75)
1429                 return 0;
1430
1431         return 1;
1432 }
1433
1434 LIBTEST_API int STDCALL 
1435 mono_test_marshal_mixed_point_2 (mixed_point *pt)
1436 {
1437         if (pt->x != 5 || pt->y != 6.75)
1438                 return 1;
1439
1440         pt->x = 10;
1441         pt->y = 12.35;
1442
1443         return 0;
1444 }
1445
1446 LIBTEST_API int STDCALL  
1447 marshal_test_ref_bool(int i, char *b1, short *b2, int *b3)
1448 {
1449     int res = 1;
1450     if (*b1 != 0 && *b1 != 1)
1451         return 1;
1452     if (*b2 != 0 && *b2 != -1) /* variant_bool */
1453         return 1;
1454     if (*b3 != 0 && *b3 != 1)
1455         return 1;
1456     if (i == ((*b1 << 2) | (-*b2 << 1) | *b3))
1457         res = 0;
1458     *b1 = !*b1;
1459     *b2 = ~*b2;
1460     *b3 = !*b3;
1461     return res;
1462 }
1463
1464 struct BoolStruct
1465 {
1466     int i;
1467     char b1;
1468     short b2; /* variant_bool */
1469     int b3;
1470 };
1471
1472 LIBTEST_API int STDCALL  
1473 marshal_test_bool_struct(struct BoolStruct *s)
1474 {
1475     int res = 1;
1476     if (s->b1 != 0 && s->b1 != 1)
1477         return 1;
1478     if (s->b2 != 0 && s->b2 != -1)
1479         return 1;
1480     if (s->b3 != 0 && s->b3 != 1)
1481         return 1;
1482     if (s->i == ((s->b1 << 2) | (-s->b2 << 1) | s->b3))
1483         res = 0;
1484     s->b1 = !s->b1;
1485     s->b2 = ~s->b2;
1486     s->b3 = !s->b3;
1487     return res;
1488 }
1489
1490 typedef struct {
1491         gint64 l;
1492 } LongStruct2;
1493
1494 typedef struct {
1495         int i;
1496         LongStruct2 l;
1497 } LongStruct;
1498
1499 LIBTEST_API int STDCALL
1500 mono_test_marshal_long_struct (LongStruct *s)
1501 {
1502         return s->i + s->l.l;
1503 }
1504
1505 LIBTEST_API void STDCALL
1506 mono_test_last_error (int err)
1507 {
1508 #ifdef WIN32
1509         SetLastError (err);
1510 #else
1511         errno = err;
1512 #endif
1513 }
1514
1515 LIBTEST_API int STDCALL 
1516 mono_test_asany (void *ptr, int what)
1517 {
1518         switch (what) {
1519         case 1:
1520                 return (*(int*)ptr == 5) ? 0 : 1;
1521         case 2:
1522                 return strcmp (ptr, "ABC") == 0 ? 0 : 1;
1523         case 3: {
1524                 simplestruct2 ss = *(simplestruct2*)ptr;
1525
1526                 if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
1527             !strcmp (ss.d, "TEST") && 
1528             ss.e == 99 && ss.f == 1.5 && ss.g == 42 && ss.h == (guint64)123)
1529                         return 0;
1530                 else
1531                         return 1;
1532         }
1533         case 4: {
1534                 GError *error = NULL;
1535                 char *s;
1536
1537                 s = g_utf16_to_utf8 (ptr, -1, NULL, NULL, &error);
1538                 if (!strcmp (s, "ABC")) {
1539                         g_free (s);
1540                         return 0;
1541                 }
1542                 else {
1543                         g_free (s);
1544                         return 1;
1545                 }
1546         }
1547         default:
1548                 g_assert_not_reached ();
1549         }
1550
1551         return 1;
1552 }
1553
1554 typedef struct
1555 {
1556         int i;
1557         int j;
1558         int k;
1559         char *s;
1560 } AsAnyStruct;
1561
1562 LIBTEST_API int STDCALL 
1563 mono_test_marshal_asany_in (void* ptr)
1564 {
1565         AsAnyStruct* asAny = ptr;
1566         int res = asAny->i + asAny->j + asAny->k;
1567
1568         return res;
1569 }
1570
1571 LIBTEST_API int STDCALL 
1572 mono_test_marshal_asany_inout (void* ptr)
1573 {
1574         AsAnyStruct* asAny = ptr;
1575         int res = asAny->i + asAny->j + asAny->k;
1576
1577         marshal_free (asAny->s);
1578
1579         asAny->i = 10;
1580         asAny->j = 20;
1581         asAny->k = 30;
1582         asAny->s = 0;
1583
1584         return res;
1585 }
1586
1587 LIBTEST_API int STDCALL 
1588 mono_test_marshal_asany_out (void* ptr)
1589 {
1590         AsAnyStruct* asAny = ptr;
1591         int res = asAny->i + asAny->j + asAny->k;
1592
1593         asAny->i = 10;
1594         asAny->j = 20;
1595         asAny->k = 30;
1596         asAny->s = 0;
1597
1598         return res;
1599 }
1600
1601 /*
1602  * AMD64 marshalling tests.
1603  */
1604
1605 typedef struct amd64_struct1 {
1606         int i;
1607         int j;
1608         int k;
1609         int l;
1610 } amd64_struct1;
1611
1612 LIBTEST_API amd64_struct1 STDCALL 
1613 mono_test_marshal_amd64_pass_return_struct1 (amd64_struct1 s)
1614 {
1615         s.i ++;
1616         s.j ++;
1617         s.k ++;
1618         s.l ++;
1619
1620         return s;
1621 }
1622
1623 LIBTEST_API amd64_struct1 STDCALL 
1624 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)
1625 {
1626         s.i ++;
1627         s.j ++;
1628         s.k ++;
1629         s.l += 1 + i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8;
1630
1631         return s;
1632 }
1633
1634 typedef struct amd64_struct2 {
1635         int i;
1636         int j;
1637 } amd64_struct2;
1638
1639 LIBTEST_API amd64_struct2 STDCALL 
1640 mono_test_marshal_amd64_pass_return_struct2 (amd64_struct2 s)
1641 {
1642         s.i ++;
1643         s.j ++;
1644
1645         return s;
1646 }
1647
1648 typedef struct amd64_struct3 {
1649         int i;
1650 } amd64_struct3;
1651
1652 LIBTEST_API amd64_struct3 STDCALL 
1653 mono_test_marshal_amd64_pass_return_struct3 (amd64_struct3 s)
1654 {
1655         s.i ++;
1656
1657         return s;
1658 }
1659
1660 typedef struct amd64_struct4 {
1661         double d1, d2;
1662 } amd64_struct4;
1663
1664 LIBTEST_API amd64_struct4 STDCALL 
1665 mono_test_marshal_amd64_pass_return_struct4 (amd64_struct4 s)
1666 {
1667         s.d1 ++;
1668         s.d2 ++;
1669
1670         return s;
1671 }
1672
1673 /*
1674  * IA64 marshalling tests.
1675  */
1676 typedef struct test_struct5 {
1677         float d1, d2;
1678 } test_struct5;
1679
1680 LIBTEST_API test_struct5 STDCALL 
1681 mono_test_marshal_ia64_pass_return_struct5 (double d1, double d2, test_struct5 s, int i, double d3, double d4)
1682 {
1683         s.d1 += d1 + d2 + i;
1684         s.d2 += d3 + d4 + i;
1685
1686         return s;
1687 }
1688
1689 typedef struct test_struct6 {
1690         double d1, d2;
1691 } test_struct6;
1692
1693 LIBTEST_API test_struct6 STDCALL 
1694 mono_test_marshal_ia64_pass_return_struct6 (double d1, double d2, test_struct6 s, int i, double d3, double d4)
1695 {
1696         s.d1 += d1 + d2 + i;
1697         s.d2 += d3 + d4;
1698
1699         return s;
1700 }
1701
1702 static guint32 custom_res [2];
1703
1704 LIBTEST_API void* STDCALL
1705 mono_test_marshal_pass_return_custom (int i, guint32 *ptr, int j)
1706 {
1707         /* ptr will be freed by CleanupNative, so make a copy */
1708         custom_res [0] = 0; /* not allocated by AllocHGlobal */
1709         custom_res [1] = ptr [1];
1710
1711         return &custom_res;
1712 }
1713
1714 LIBTEST_API int STDCALL 
1715 mono_test_marshal_pass_out_custom (int i, guint32 **ptr, int j)
1716 {
1717         custom_res [0] = 0;
1718         custom_res [1] = i + j + 10;
1719
1720         *ptr = custom_res;
1721
1722         return 0;
1723 }
1724
1725 LIBTEST_API int STDCALL 
1726 mono_test_marshal_pass_inout_custom (int i, guint32 *ptr, int j)
1727 {
1728         ptr [0] = 0;
1729         ptr [1] = i + ptr [1] + j;
1730
1731         return 0;
1732 }
1733
1734 LIBTEST_API int STDCALL 
1735 mono_test_marshal_pass_out_byval_custom (int i, guint32 *ptr, int j)
1736 {
1737         return ptr == NULL ? 0 : 1;
1738 }
1739
1740 LIBTEST_API int STDCALL 
1741 mono_test_marshal_pass_byref_custom (int i, guint32 **ptr, int j)
1742 {
1743         (*ptr)[1] += i + j;
1744
1745         return 0;
1746 }
1747
1748 LIBTEST_API void* STDCALL
1749 mono_test_marshal_pass_return_custom2 (int i, guint32 *ptr, int j)
1750 {
1751         g_assert_not_reached ();
1752
1753         return NULL;
1754 }
1755
1756 LIBTEST_API void* STDCALL
1757 mono_test_marshal_pass_return_custom_null (int i, guint32 *ptr, int j)
1758 {
1759         g_assert (ptr == NULL);
1760
1761         return NULL;
1762 }
1763
1764 typedef void *(STDCALL *PassReturnPtrDelegate) (void *ptr);
1765
1766 LIBTEST_API int STDCALL 
1767 mono_test_marshal_pass_return_custom_in_delegate (PassReturnPtrDelegate del)
1768 {
1769         guint32 buf [2];
1770         guint32 res;
1771         guint32 *ptr;
1772
1773         buf [0] = 0;
1774         buf [1] = 10;
1775
1776         ptr = del (&buf);
1777
1778         res = ptr [1];
1779
1780 #ifdef WIN32
1781         /* FIXME: Freed with FreeHGlobal */
1782 #else
1783         g_free (ptr);
1784 #endif
1785
1786         return res;
1787 }
1788
1789 LIBTEST_API int STDCALL 
1790 mono_test_marshal_pass_return_custom_null_in_delegate (PassReturnPtrDelegate del)
1791 {
1792         void *ptr = del (NULL);
1793
1794         return (ptr == NULL) ? 15 : 0;
1795 }
1796
1797 typedef void (STDCALL *CustomOutParamDelegate) (void **pptr);
1798
1799 LIBTEST_API int STDCALL 
1800 mono_test_marshal_custom_out_param_delegate (CustomOutParamDelegate del)
1801 {
1802         void* pptr = del;
1803
1804         del (&pptr);
1805
1806         if(pptr != NULL)
1807                 return 1;
1808
1809         return 0;
1810 }
1811
1812 typedef int (STDCALL *ReturnEnumDelegate) (int e);
1813
1814 LIBTEST_API int STDCALL 
1815 mono_test_marshal_return_enum_delegate (ReturnEnumDelegate func)
1816 {
1817         return func (1);
1818 }
1819
1820 typedef struct {
1821         int a, b, c;
1822         gint64 d;
1823 } BlittableStruct;
1824         
1825 typedef BlittableStruct (STDCALL *SimpleDelegate10) (BlittableStruct ss);
1826
1827 LIBTEST_API int STDCALL 
1828 mono_test_marshal_blittable_struct_delegate (SimpleDelegate10 delegate)
1829 {
1830         BlittableStruct ss, res;
1831
1832         ss.a = 1;
1833         ss.b = 2;
1834         ss.c = 3;
1835         ss.d = 55;
1836
1837         res = delegate (ss);
1838         if (! ((res.a == -1) && (res.b == -2) && (res.c == -3) && (res.d == -55)))
1839                 return 1;
1840
1841         return 0;
1842 }
1843
1844 LIBTEST_API int STDCALL 
1845 mono_test_stdcall_name_mangling (int a, int b, int c)
1846 {
1847         return a + b + c;
1848 }
1849
1850 /*
1851  * PASSING AND RETURNING SMALL STRUCTURES FROM DELEGATES TESTS
1852  */
1853
1854 typedef struct {
1855         int i;
1856 } SmallStruct1;
1857         
1858 typedef SmallStruct1 (STDCALL *SmallStructDelegate1) (SmallStruct1 ss);
1859
1860 LIBTEST_API int STDCALL 
1861 mono_test_marshal_small_struct_delegate1 (SmallStructDelegate1 delegate)
1862 {
1863         SmallStruct1 ss, res;
1864
1865         ss.i = 1;
1866
1867         res = delegate (ss);
1868         if (! (res.i == -1))
1869                 return 1;
1870
1871         return 0;
1872 }
1873
1874 typedef struct {
1875         gint16 i, j;
1876 } SmallStruct2;
1877         
1878 typedef SmallStruct2 (STDCALL *SmallStructDelegate2) (SmallStruct2 ss);
1879
1880 LIBTEST_API int STDCALL 
1881 mono_test_marshal_small_struct_delegate2 (SmallStructDelegate2 delegate)
1882 {
1883         SmallStruct2 ss, res;
1884
1885         ss.i = 2;
1886         ss.j = 3;
1887
1888         res = delegate (ss);
1889         if (! ((res.i == -2) && (res.j == -3)))
1890                 return 1;
1891
1892         return 0;
1893 }
1894
1895 typedef struct {
1896         gint16 i;
1897         gint8 j;
1898 } SmallStruct3;
1899         
1900 typedef SmallStruct3 (STDCALL *SmallStructDelegate3) (SmallStruct3 ss);
1901
1902 LIBTEST_API int STDCALL 
1903 mono_test_marshal_small_struct_delegate3 (SmallStructDelegate3 delegate)
1904 {
1905         SmallStruct3 ss, res;
1906
1907         ss.i = 1;
1908         ss.j = 2;
1909
1910         res = delegate (ss);
1911         if (! ((res.i == -1) && (res.j == -2)))
1912                 return 1;
1913
1914         return 0;
1915 }
1916
1917 typedef struct {
1918         gint16 i;
1919 } SmallStruct4;
1920         
1921 typedef SmallStruct4 (STDCALL *SmallStructDelegate4) (SmallStruct4 ss);
1922
1923 LIBTEST_API int STDCALL 
1924 mono_test_marshal_small_struct_delegate4 (SmallStructDelegate4 delegate)
1925 {
1926         SmallStruct4 ss, res;
1927
1928         ss.i = 1;
1929
1930         res = delegate (ss);
1931         if (! (res.i == -1))
1932                 return 1;
1933
1934         return 0;
1935 }
1936
1937 typedef struct {
1938         gint64 i;
1939 } SmallStruct5;
1940         
1941 typedef SmallStruct5 (STDCALL *SmallStructDelegate5) (SmallStruct5 ss);
1942
1943 LIBTEST_API int STDCALL 
1944 mono_test_marshal_small_struct_delegate5 (SmallStructDelegate5 delegate)
1945 {
1946         SmallStruct5 ss, res;
1947
1948         ss.i = 5;
1949
1950         res = delegate (ss);
1951         if (! (res.i == -5))
1952                 return 1;
1953
1954         return 0;
1955 }
1956
1957 typedef struct {
1958         int i, j;
1959 } SmallStruct6;
1960         
1961 typedef SmallStruct6 (STDCALL *SmallStructDelegate6) (SmallStruct6 ss);
1962
1963 LIBTEST_API int STDCALL 
1964 mono_test_marshal_small_struct_delegate6 (SmallStructDelegate6 delegate)
1965 {
1966         SmallStruct6 ss, res;
1967
1968         ss.i = 1;
1969         ss.j = 2;
1970
1971         res = delegate (ss);
1972         if (! ((res.i == -1) && (res.j == -2)))
1973                 return 1;
1974
1975         return 0;
1976 }
1977
1978 typedef struct {
1979         int i;
1980         gint16 j;
1981 } SmallStruct7;
1982         
1983 typedef SmallStruct7 (STDCALL *SmallStructDelegate7) (SmallStruct7 ss);
1984
1985 LIBTEST_API int STDCALL 
1986 mono_test_marshal_small_struct_delegate7 (SmallStructDelegate7 delegate)
1987 {
1988         SmallStruct7 ss, res;
1989
1990         ss.i = 1;
1991         ss.j = 2;
1992
1993         res = delegate (ss);
1994         if (! ((res.i == -1) && (res.j == -2)))
1995                 return 1;
1996
1997         return 0;
1998 }
1999
2000 typedef struct {
2001         float i;
2002 } SmallStruct8;
2003         
2004 typedef SmallStruct8 (STDCALL *SmallStructDelegate8) (SmallStruct8 ss);
2005
2006 LIBTEST_API int STDCALL 
2007 mono_test_marshal_small_struct_delegate8 (SmallStructDelegate8 delegate)
2008 {
2009         SmallStruct8 ss, res;
2010
2011         ss.i = 1.0;
2012
2013         res = delegate (ss);
2014         if (! ((res.i == -1.0)))
2015                 return 1;
2016
2017         return 0;
2018 }
2019
2020 typedef struct {
2021         double i;
2022 } SmallStruct9;
2023         
2024 typedef SmallStruct9 (STDCALL *SmallStructDelegate9) (SmallStruct9 ss);
2025
2026 LIBTEST_API int STDCALL 
2027 mono_test_marshal_small_struct_delegate9 (SmallStructDelegate9 delegate)
2028 {
2029         SmallStruct9 ss, res;
2030
2031         ss.i = 1.0;
2032
2033         res = delegate (ss);
2034         if (! ((res.i == -1.0)))
2035                 return 1;
2036
2037         return 0;
2038 }
2039
2040 typedef struct {
2041         float i, j;
2042 } SmallStruct10;
2043         
2044 typedef SmallStruct10 (STDCALL *SmallStructDelegate10) (SmallStruct10 ss);
2045
2046 LIBTEST_API int STDCALL 
2047 mono_test_marshal_small_struct_delegate10 (SmallStructDelegate10 delegate)
2048 {
2049         SmallStruct10 ss, res;
2050
2051         ss.i = 1.0;
2052         ss.j = 2.0;
2053
2054         res = delegate (ss);
2055         if (! ((res.i == -1.0) && (res.j == -2.0)))
2056                 return 1;
2057
2058         return 0;
2059 }
2060
2061 typedef struct {
2062         float i;
2063         int j;
2064 } SmallStruct11;
2065         
2066 typedef SmallStruct11 (STDCALL *SmallStructDelegate11) (SmallStruct11 ss);
2067
2068 LIBTEST_API int STDCALL 
2069 mono_test_marshal_small_struct_delegate11 (SmallStructDelegate11 delegate)
2070 {
2071         SmallStruct11 ss, res;
2072
2073         ss.i = 1.0;
2074         ss.j = 2;
2075
2076         res = delegate (ss);
2077         if (! ((res.i == -1.0) && (res.j == -2)))
2078                 return 1;
2079
2080         return 0;
2081 }
2082
2083 typedef int (STDCALL *ArrayDelegate) (int i, char *j, void *arr);
2084
2085 LIBTEST_API int STDCALL 
2086 mono_test_marshal_array_delegate (void *arr, int len, ArrayDelegate del)
2087 {
2088         return del (len, NULL, arr);
2089 }
2090
2091 typedef int (STDCALL *ArrayDelegateLong) (gint64 i, char *j, void *arr);
2092
2093 LIBTEST_API int STDCALL 
2094 mono_test_marshal_array_delegate_long (void *arr, gint64 len, ArrayDelegateLong del)
2095 {
2096         return del (len, NULL, arr);
2097 }
2098
2099 LIBTEST_API int STDCALL 
2100 mono_test_marshal_out_array_delegate (int *arr, int len, ArrayDelegate del)
2101 {
2102         del (len, NULL, arr);
2103
2104         if ((arr [0] != 1) || (arr [1] != 2))
2105                 return 1;
2106         else
2107                 return 0;
2108 }
2109
2110 typedef gunichar2* (STDCALL *UnicodeStringDelegate) (gunichar2 *message);
2111
2112 LIBTEST_API int STDCALL 
2113 mono_test_marshal_return_unicode_string_delegate (UnicodeStringDelegate del)
2114 {
2115         const char m[] = "abcdef";
2116         gunichar2 *s2, *res;
2117         glong len;
2118
2119         s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
2120
2121         res = del (s2);
2122
2123         marshal_free (res);
2124
2125         return 0;
2126 }
2127
2128 LIBTEST_API int STDCALL 
2129 mono_test_marshal_out_string_array_delegate (char **arr, int len, ArrayDelegate del)
2130 {
2131         del (len, NULL, arr);
2132
2133         if (!strcmp (arr [0], "ABC") && !strcmp (arr [1], "DEF"))
2134                 return 0;
2135         else
2136                 return 1;
2137 }
2138
2139 typedef int (*CdeclDelegate) (int i, int j);
2140
2141 LIBTEST_API int STDCALL 
2142 mono_test_marshal_cdecl_delegate (CdeclDelegate del)
2143 {
2144         int i;
2145
2146         for (i = 0; i < 1000; ++i)
2147                 del (1, 2);
2148
2149         return 0;
2150 }
2151
2152 typedef char** (STDCALL *ReturnStringArrayDelegate) (int i);
2153
2154 LIBTEST_API int STDCALL 
2155 mono_test_marshal_return_string_array_delegate (ReturnStringArrayDelegate d)
2156 {
2157         char **arr = d (2);
2158         int res;
2159
2160         if (arr == NULL)
2161                 return 3;
2162
2163         if (strcmp (arr [0], "ABC") || strcmp (arr [1], "DEF"))
2164                 res = 1;
2165         else
2166                 res = 0;
2167
2168         marshal_free (arr);
2169
2170         return res;
2171 }
2172
2173 typedef int (STDCALL *ByrefStringDelegate) (char **s);
2174
2175 LIBTEST_API int STDCALL 
2176 mono_test_marshal_byref_string_delegate (ByrefStringDelegate d)
2177 {
2178         char *s = (char*)"ABC";
2179         int res;
2180
2181         res = d (&s);
2182         if (res != 0)
2183                 return res;
2184
2185         if (!strcmp (s, "DEF"))
2186                 res = 0;
2187         else
2188                 res = 2;
2189
2190         marshal_free (s);
2191
2192         return res;
2193 }
2194
2195 LIBTEST_API int STDCALL 
2196 add_delegate (int i, int j)
2197 {
2198         return i + j;
2199 }
2200
2201 LIBTEST_API gpointer STDCALL 
2202 mono_test_marshal_return_fnptr (void)
2203 {
2204         return &add_delegate;
2205 }
2206
2207 LIBTEST_API int STDCALL 
2208 mono_xr (int code)
2209 {
2210         printf ("codigo %x\n", code);
2211         return code + 1234;
2212 }
2213
2214 typedef struct {
2215         int handle;
2216 } HandleRef;
2217
2218 LIBTEST_API HandleRef STDCALL 
2219 mono_xr_as_handle (int code)
2220 {
2221         HandleRef ref;
2222
2223         memset (&ref, 0, sizeof (ref));
2224
2225         return ref;
2226 }
2227  
2228 typedef struct {
2229         int   a;
2230         void *handle1;
2231         void *handle2;
2232         int   b;
2233 } HandleStructs;
2234
2235 LIBTEST_API int STDCALL 
2236 mono_safe_handle_struct_ref (HandleStructs *x)
2237 {
2238         printf ("Dingus Ref! \n");
2239         printf ("Values: %d %d %p %p\n", x->a, x->b, x->handle1, x->handle2);
2240         if (x->a != 1234)
2241                 return 1;
2242         if (x->b != 8743)
2243                 return 2;
2244
2245         if (x->handle1 != (void*) 0x7080feed)
2246                 return 3;
2247
2248         if (x->handle2 != (void*) 0x1234abcd)
2249                 return 4;
2250
2251         return 0xf00d;
2252 }
2253
2254 LIBTEST_API int STDCALL 
2255 mono_safe_handle_struct (HandleStructs x)
2256 {
2257         printf ("Dingus Standard! \n");
2258         printf ("Values: %d %d %p %p\n", x.a, x.b, x.handle1, x.handle2);
2259         if (x.a != 1234)
2260                 return 1;
2261         if (x.b != 8743)
2262                 return 2;
2263
2264         if (x.handle1 != (void*) 0x7080feed)
2265                 return 3;
2266
2267         if (x.handle2 != (void*) 0x1234abcd)
2268                 return 4;
2269         
2270         return 0xf00f;
2271 }
2272
2273 typedef struct {
2274         void *a;
2275 } TrivialHandle;
2276
2277 LIBTEST_API int STDCALL 
2278 mono_safe_handle_struct_simple (TrivialHandle x)
2279 {
2280         printf ("The value is %p\n", x.a);
2281         return ((int)(gsize)x.a) * 2;
2282 }
2283
2284 LIBTEST_API int STDCALL 
2285 mono_safe_handle_return (void)
2286 {
2287         return 0x1000f00d;
2288 }
2289
2290 LIBTEST_API void STDCALL
2291 mono_safe_handle_ref (void **handle)
2292 {
2293         if (*handle != 0){
2294                 *handle = (void *) 0xbad;
2295                 return;
2296         }
2297
2298         *handle = (void *) 0x800d;
2299 }
2300 /*
2301  * COM INTEROP TESTS
2302  */
2303
2304 #ifndef WIN32
2305
2306 typedef struct {
2307         guint16 vt;
2308         guint16 wReserved1;
2309         guint16 wReserved2;
2310         guint16 wReserved3;
2311         union {
2312                 gint64 llVal;
2313                 gint32 lVal;
2314                 guint8  bVal;
2315                 gint16 iVal;
2316                 float  fltVal;
2317                 double dblVal;
2318                 gint16 boolVal;
2319                 gunichar2* bstrVal;
2320                 gint8 cVal;
2321                 guint16 uiVal;
2322                 guint32 ulVal;
2323                 guint64 ullVal;
2324                 struct {
2325                         gpointer pvRecord;
2326                         gpointer pRecInfo;
2327                 };
2328         };
2329 } VARIANT;
2330
2331 typedef enum {
2332         VARIANT_TRUE = -1,
2333         VARIANT_FALSE = 0
2334 } VariantBool;
2335
2336 typedef enum {
2337         VT_EMPTY = 0,
2338         VT_NULL = 1,
2339         VT_I2 = 2,
2340         VT_I4 = 3,
2341         VT_R4 = 4,
2342         VT_R8 = 5,
2343         VT_CY = 6,
2344         VT_DATE = 7,
2345         VT_BSTR = 8,
2346         VT_DISPATCH = 9,
2347         VT_ERROR = 10,
2348         VT_BOOL = 11,
2349         VT_VARIANT = 12,
2350         VT_UNKNOWN = 13,
2351         VT_DECIMAL = 14,
2352         VT_I1 = 16,
2353         VT_UI1 = 17,
2354         VT_UI2 = 18,
2355         VT_UI4 = 19,
2356         VT_I8 = 20,
2357         VT_UI8 = 21,
2358         VT_INT = 22,
2359         VT_UINT = 23,
2360         VT_VOID = 24,
2361         VT_HRESULT = 25,
2362         VT_PTR = 26,
2363         VT_SAFEARRAY = 27,
2364         VT_CARRAY = 28,
2365         VT_USERDEFINED = 29,
2366         VT_LPSTR = 30,
2367         VT_LPWSTR = 31,
2368         VT_RECORD = 36,
2369         VT_FILETIME = 64,
2370         VT_BLOB = 65,
2371         VT_STREAM = 66,
2372         VT_STORAGE = 67,
2373         VT_STREAMED_OBJECT = 68,
2374         VT_STORED_OBJECT = 69,
2375         VT_BLOB_OBJECT = 70,
2376         VT_CF = 71,
2377         VT_CLSID = 72,
2378         VT_VECTOR = 4096,
2379         VT_ARRAY = 8192,
2380         VT_BYREF = 16384
2381 } VarEnum;
2382
2383 void VariantInit(VARIANT* vt)
2384 {
2385         vt->vt = VT_EMPTY;
2386 }
2387
2388 typedef struct
2389 {
2390         guint32 a;
2391         guint16 b;
2392         guint16 c;
2393         guint8 d[8];
2394 } GUID;
2395
2396 #define S_OK 0
2397
2398 #endif
2399
2400 LIBTEST_API int STDCALL 
2401 mono_test_marshal_bstr_in(gunichar2* bstr)
2402 {
2403         gint32 result = 0;
2404         gchar* bstr_utf8 = g_utf16_to_utf8 (bstr, -1, NULL, NULL, NULL);
2405         result = strcmp("mono_test_marshal_bstr_in", bstr_utf8);
2406         g_free(bstr_utf8);
2407         if (result == 0)
2408                 return 0;
2409         return 1;
2410 }
2411
2412 LIBTEST_API int STDCALL 
2413 mono_test_marshal_bstr_out(gunichar2** bstr)
2414 {
2415         *bstr = marshal_bstr_alloc ("mono_test_marshal_bstr_out");
2416         return 0;
2417 }
2418
2419 LIBTEST_API int STDCALL 
2420 mono_test_marshal_bstr_in_null(gunichar2* bstr)
2421 {
2422         if (!bstr)
2423                 return 0;
2424         return 1;
2425 }
2426
2427 LIBTEST_API int STDCALL 
2428 mono_test_marshal_bstr_out_null(gunichar2** bstr)
2429 {
2430         *bstr = NULL;
2431         return 0;
2432 }
2433
2434 LIBTEST_API int STDCALL 
2435 mono_test_marshal_variant_in_sbyte(VARIANT variant)
2436 {
2437         if (variant.vt == VT_I1 && variant.cVal == 100)
2438                 return 0;
2439         return 1;
2440 }
2441
2442 LIBTEST_API int STDCALL 
2443 mono_test_marshal_variant_in_byte(VARIANT variant)
2444 {
2445         if (variant.vt == VT_UI1 && variant.bVal == 100)
2446                 return 0;
2447         return 1;
2448 }
2449
2450 LIBTEST_API int STDCALL 
2451 mono_test_marshal_variant_in_short(VARIANT variant)
2452 {
2453         if (variant.vt == VT_I2 && variant.iVal == 314)
2454                 return 0;
2455         return 1;
2456 }
2457
2458 LIBTEST_API int STDCALL 
2459 mono_test_marshal_variant_in_ushort(VARIANT variant)
2460 {
2461         if (variant.vt == VT_UI2 && variant.uiVal == 314)
2462                 return 0;
2463         return 1;
2464 }
2465
2466 LIBTEST_API int STDCALL 
2467 mono_test_marshal_variant_in_int(VARIANT variant)
2468 {
2469         if (variant.vt == VT_I4 && variant.lVal == 314)
2470                 return 0;
2471         return 1;
2472 }
2473
2474 LIBTEST_API int STDCALL 
2475 mono_test_marshal_variant_in_uint(VARIANT variant)
2476 {
2477         if (variant.vt == VT_UI4 && variant.ulVal == 314)
2478                 return 0;
2479         return 1;
2480 }
2481
2482 LIBTEST_API int STDCALL 
2483 mono_test_marshal_variant_in_long(VARIANT variant)
2484 {
2485         if (variant.vt == VT_I8 && variant.llVal == 314)
2486                 return 0;
2487         return 1;
2488 }
2489
2490 LIBTEST_API int STDCALL 
2491 mono_test_marshal_variant_in_ulong(VARIANT variant)
2492 {
2493         if (variant.vt == VT_UI8 && variant.ullVal == 314)
2494                 return 0;
2495         return 1;
2496 }
2497
2498 LIBTEST_API int STDCALL 
2499 mono_test_marshal_variant_in_float(VARIANT variant)
2500 {
2501         if (variant.vt == VT_R4 && (variant.fltVal - 3.14)/3.14 < .001)
2502                 return 0;
2503         return 1;
2504 }
2505
2506 LIBTEST_API int STDCALL 
2507 mono_test_marshal_variant_in_double(VARIANT variant)
2508 {
2509         if (variant.vt == VT_R8 && (variant.dblVal - 3.14)/3.14 < .001)
2510                 return 0;
2511         return 1;
2512 }
2513
2514 LIBTEST_API int STDCALL 
2515 mono_test_marshal_variant_in_bstr(VARIANT variant)
2516 {
2517         gint32 result = 0;
2518         gchar* bstr_utf8 = g_utf16_to_utf8 (variant.bstrVal, -1, NULL, NULL, NULL);
2519         result = strcmp("PI", bstr_utf8);
2520         g_free(bstr_utf8);
2521
2522         if (variant.vt == VT_BSTR && !result)
2523                 return 0;
2524         return 1;
2525 }
2526
2527 LIBTEST_API int STDCALL 
2528 mono_test_marshal_variant_in_bool_true (VARIANT variant)
2529 {
2530         if (variant.vt == VT_BOOL && variant.boolVal == VARIANT_TRUE)
2531                 return 0;
2532         return 1;
2533 }
2534
2535 LIBTEST_API int STDCALL 
2536 mono_test_marshal_variant_in_bool_false (VARIANT variant)
2537 {
2538         if (variant.vt == VT_BOOL && variant.boolVal == VARIANT_FALSE)
2539                 return 0;
2540         return 1;
2541 }
2542
2543 LIBTEST_API int STDCALL 
2544 mono_test_marshal_variant_out_sbyte(VARIANT* variant)
2545 {
2546         variant->vt = VT_I1;
2547         variant->cVal = 100;
2548
2549         return 0;
2550 }
2551
2552 LIBTEST_API int STDCALL 
2553 mono_test_marshal_variant_out_byte(VARIANT* variant)
2554 {       
2555         variant->vt = VT_UI1;
2556         variant->bVal = 100;
2557
2558         return 0;
2559 }
2560
2561 LIBTEST_API int STDCALL 
2562 mono_test_marshal_variant_out_short(VARIANT* variant)
2563 {
2564         variant->vt = VT_I2;
2565         variant->iVal = 314;
2566
2567         return 0;
2568 }
2569
2570 LIBTEST_API int STDCALL 
2571 mono_test_marshal_variant_out_ushort(VARIANT* variant)
2572 {
2573         variant->vt = VT_UI2;
2574         variant->uiVal = 314;
2575
2576         return 0;
2577 }
2578
2579 LIBTEST_API int STDCALL 
2580 mono_test_marshal_variant_out_int(VARIANT* variant)
2581 {
2582         variant->vt = VT_I4;
2583         variant->lVal = 314;
2584
2585         return 0;
2586 }
2587
2588 LIBTEST_API int STDCALL 
2589 mono_test_marshal_variant_out_uint(VARIANT* variant)
2590 {
2591         variant->vt = VT_UI4;
2592         variant->ulVal = 314;
2593
2594         return 0;
2595 }
2596
2597 LIBTEST_API int STDCALL 
2598 mono_test_marshal_variant_out_long(VARIANT* variant)
2599 {
2600         variant->vt = VT_I8;
2601         variant->llVal = 314;
2602
2603         return 0;
2604 }
2605
2606 LIBTEST_API int STDCALL 
2607 mono_test_marshal_variant_out_ulong(VARIANT* variant)
2608 {
2609         variant->vt = VT_UI8;
2610         variant->ullVal = 314;
2611
2612         return 0;
2613 }
2614
2615 LIBTEST_API int STDCALL 
2616 mono_test_marshal_variant_out_float(VARIANT* variant)
2617 {
2618         variant->vt = VT_R4;
2619         variant->fltVal = 3.14;
2620
2621         return 0;
2622 }
2623
2624 LIBTEST_API int STDCALL 
2625 mono_test_marshal_variant_out_double(VARIANT* variant)
2626 {
2627         variant->vt = VT_R8;
2628         variant->dblVal = 3.14;
2629
2630         return 0;
2631 }
2632
2633 LIBTEST_API int STDCALL 
2634 mono_test_marshal_variant_out_bstr(VARIANT* variant)
2635 {
2636         variant->vt = VT_BSTR;
2637         variant->bstrVal = marshal_bstr_alloc("PI");
2638
2639         return 0;
2640 }
2641
2642 LIBTEST_API int STDCALL 
2643 mono_test_marshal_variant_out_bool_true (VARIANT* variant)
2644 {
2645         variant->vt = VT_BOOL;
2646         variant->boolVal = VARIANT_TRUE;
2647
2648         return 0;
2649 }
2650
2651 LIBTEST_API int STDCALL 
2652 mono_test_marshal_variant_out_bool_false (VARIANT* variant)
2653 {
2654         variant->vt = VT_BOOL;
2655         variant->boolVal = VARIANT_FALSE;
2656
2657         return 0;
2658 }
2659
2660 typedef int (STDCALL *VarFunc) (int vt, VARIANT variant);
2661 typedef int (STDCALL *VarRefFunc) (int vt, VARIANT* variant);
2662
2663 LIBTEST_API int STDCALL 
2664 mono_test_marshal_variant_in_sbyte_unmanaged(VarFunc func)
2665 {
2666         VARIANT vt;
2667         vt.vt = VT_I1;
2668         vt.cVal = -100;
2669         return func (VT_I1, vt);
2670 }
2671
2672 LIBTEST_API int STDCALL 
2673 mono_test_marshal_variant_in_byte_unmanaged(VarFunc func)
2674 {
2675         VARIANT vt;
2676         vt.vt = VT_UI1;
2677         vt.bVal = 100;
2678         return func (VT_UI1, vt);
2679 }
2680
2681 LIBTEST_API int STDCALL 
2682 mono_test_marshal_variant_in_short_unmanaged(VarFunc func)
2683 {
2684         VARIANT vt;
2685         vt.vt = VT_I2;
2686         vt.iVal = -100;
2687         return func (VT_I2, vt);
2688 }
2689
2690 LIBTEST_API int STDCALL 
2691 mono_test_marshal_variant_in_ushort_unmanaged(VarFunc func)
2692 {
2693         VARIANT vt;
2694         vt.vt = VT_UI2;
2695         vt.uiVal = 100;
2696         return func (VT_UI2, vt);
2697 }
2698
2699 LIBTEST_API int STDCALL 
2700 mono_test_marshal_variant_in_int_unmanaged(VarFunc func)
2701 {
2702         VARIANT vt;
2703         vt.vt = VT_I4;
2704         vt.lVal = -100;
2705         return func (VT_I4, vt);
2706 }
2707
2708 LIBTEST_API int STDCALL 
2709 mono_test_marshal_variant_in_uint_unmanaged(VarFunc func)
2710 {
2711         VARIANT vt;
2712         vt.vt = VT_UI4;
2713         vt.ulVal = 100;
2714         return func (VT_UI4, vt);
2715 }
2716
2717 LIBTEST_API int STDCALL 
2718 mono_test_marshal_variant_in_long_unmanaged(VarFunc func)
2719 {
2720         VARIANT vt;
2721         vt.vt = VT_I8;
2722         vt.llVal = -100;
2723         return func (VT_I8, vt);
2724 }
2725
2726 LIBTEST_API int STDCALL 
2727 mono_test_marshal_variant_in_ulong_unmanaged(VarFunc func)
2728 {
2729         VARIANT vt;
2730         vt.vt = VT_UI8;
2731         vt.ullVal = 100;
2732         return func (VT_UI8, vt);
2733 }
2734
2735 LIBTEST_API int STDCALL 
2736 mono_test_marshal_variant_in_float_unmanaged(VarFunc func)
2737 {
2738         VARIANT vt;
2739         vt.vt = VT_R4;
2740         vt.fltVal = 3.14;
2741         return func (VT_R4, vt);
2742 }
2743
2744 LIBTEST_API int STDCALL 
2745 mono_test_marshal_variant_in_double_unmanaged(VarFunc func)
2746 {
2747         VARIANT vt;
2748         vt.vt = VT_R8;
2749         vt.dblVal = 3.14;
2750         return func (VT_R8, vt);
2751 }
2752
2753 LIBTEST_API int STDCALL 
2754 mono_test_marshal_variant_in_bstr_unmanaged(VarFunc func)
2755 {
2756         VARIANT vt;
2757         vt.vt = VT_BSTR;
2758         vt.bstrVal = marshal_bstr_alloc("PI");
2759         return func (VT_BSTR, vt);
2760 }
2761
2762 LIBTEST_API int STDCALL 
2763 mono_test_marshal_variant_in_bool_true_unmanaged(VarFunc func)
2764 {
2765         VARIANT vt;
2766         vt.vt = VT_BOOL;
2767         vt.boolVal = VARIANT_TRUE;
2768         return func (VT_BOOL, vt);
2769 }
2770
2771 LIBTEST_API int STDCALL 
2772 mono_test_marshal_variant_in_bool_false_unmanaged(VarFunc func)
2773 {
2774         VARIANT vt;
2775         vt.vt = VT_BOOL;
2776         vt.boolVal = VARIANT_FALSE;
2777         return func (VT_BOOL, vt);
2778 }
2779
2780 LIBTEST_API int STDCALL 
2781 mono_test_marshal_variant_out_sbyte_unmanaged(VarRefFunc func)
2782 {
2783         VARIANT vt;
2784         VariantInit (&vt);
2785         func (VT_I1, &vt);
2786         if (vt.vt == VT_I1 && vt.cVal == -100)
2787                 return 0;
2788         return 1;
2789 }
2790
2791 LIBTEST_API int STDCALL 
2792 mono_test_marshal_variant_out_byte_unmanaged(VarRefFunc func)
2793 {
2794         VARIANT vt;
2795         VariantInit (&vt);
2796         func (VT_UI1, &vt);
2797         if (vt.vt == VT_UI1 && vt.bVal == 100)
2798                 return 0;
2799         return 1;
2800 }
2801
2802 LIBTEST_API int STDCALL 
2803 mono_test_marshal_variant_out_short_unmanaged(VarRefFunc func)
2804 {
2805         VARIANT vt;
2806         VariantInit (&vt);
2807         func (VT_I2, &vt);
2808         if (vt.vt == VT_I2 && vt.iVal == -100)
2809                 return 0;
2810         return 1;
2811 }
2812
2813 LIBTEST_API int STDCALL 
2814 mono_test_marshal_variant_out_ushort_unmanaged(VarRefFunc func)
2815 {
2816         VARIANT vt;
2817         VariantInit (&vt);
2818         func (VT_UI2, &vt);
2819         if (vt.vt == VT_UI2 && vt.uiVal == 100)
2820                 return 0;
2821         return 1;
2822 }
2823
2824 LIBTEST_API int STDCALL 
2825 mono_test_marshal_variant_out_int_unmanaged(VarRefFunc func)
2826 {
2827         VARIANT vt;
2828         VariantInit (&vt);
2829         func (VT_I4, &vt);
2830         if (vt.vt == VT_I4 && vt.lVal == -100)
2831                 return 0;
2832         return 1;
2833 }
2834
2835 LIBTEST_API int STDCALL 
2836 mono_test_marshal_variant_out_uint_unmanaged(VarRefFunc func)
2837 {
2838         VARIANT vt;
2839         VariantInit (&vt);
2840         func (VT_UI4, &vt);
2841         if (vt.vt == VT_UI4 && vt.ulVal == 100)
2842                 return 0;
2843         return 1;
2844 }
2845
2846 LIBTEST_API int STDCALL 
2847 mono_test_marshal_variant_out_long_unmanaged(VarRefFunc func)
2848 {
2849         VARIANT vt;
2850         VariantInit (&vt);
2851         func (VT_I8, &vt);
2852         if (vt.vt == VT_I8 && vt.llVal == -100)
2853                 return 0;
2854         return 1;
2855 }
2856
2857 LIBTEST_API int STDCALL 
2858 mono_test_marshal_variant_out_ulong_unmanaged(VarRefFunc func)
2859 {
2860         VARIANT vt;
2861         VariantInit (&vt);
2862         func (VT_UI8, &vt);
2863         if (vt.vt == VT_UI8 && vt.ullVal == 100)
2864                 return 0;
2865         return 1;
2866 }
2867
2868 LIBTEST_API int STDCALL 
2869 mono_test_marshal_variant_out_float_unmanaged(VarRefFunc func)
2870 {
2871         VARIANT vt;
2872         VariantInit (&vt);
2873         func (VT_R4, &vt);
2874         if (vt.vt == VT_R4 && fabs (vt.fltVal - 3.14f) < 1e-10)
2875                 return 0;
2876         return 1;
2877 }
2878
2879 LIBTEST_API int STDCALL 
2880 mono_test_marshal_variant_out_double_unmanaged(VarRefFunc func)
2881 {
2882         VARIANT vt;
2883         VariantInit (&vt);
2884         func (VT_R8, &vt);
2885         if (vt.vt == VT_R8 && fabs (vt.dblVal - 3.14) < 1e-10)
2886                 return 0;
2887         return 1;
2888 }
2889
2890 LIBTEST_API int STDCALL 
2891 mono_test_marshal_variant_out_bstr_unmanaged(VarRefFunc func)
2892 {
2893         VARIANT vt;
2894         gchar* bstr_utf8;
2895         gint32 result = 0;
2896
2897
2898         VariantInit (&vt);
2899         func (VT_BSTR, &vt);
2900         bstr_utf8 = g_utf16_to_utf8 (vt.bstrVal, -1, NULL, NULL, NULL);
2901         result = strcmp("PI", bstr_utf8);
2902         g_free(bstr_utf8);
2903         if (vt.vt == VT_BSTR && !result)
2904                 return 0;
2905         return 1;
2906 }
2907
2908 LIBTEST_API int STDCALL 
2909 mono_test_marshal_variant_out_bool_true_unmanaged(VarRefFunc func)
2910 {
2911         VARIANT vt;
2912         VariantInit (&vt);
2913         func (VT_BOOL, &vt);
2914         if (vt.vt == VT_BOOL && vt.boolVal == VARIANT_TRUE)
2915                 return 0;
2916         return 1;
2917 }
2918
2919 LIBTEST_API int STDCALL 
2920 mono_test_marshal_variant_out_bool_false_unmanaged(VarRefFunc func)
2921 {
2922         VARIANT vt;
2923         VariantInit (&vt);
2924         func (VT_BOOL, &vt);
2925         if (vt.vt == VT_BOOL && vt.boolVal == VARIANT_TRUE)
2926                 return 0;
2927         return 1;
2928 }
2929
2930 typedef struct MonoComObject MonoComObject;
2931
2932 typedef struct
2933 {
2934         int (STDCALL *QueryInterface)(MonoComObject* pUnk, gpointer riid, gpointer* ppv);
2935         int (STDCALL *AddRef)(MonoComObject* pUnk);
2936         int (STDCALL *Release)(MonoComObject* pUnk);
2937         int (STDCALL *get_ITest)(MonoComObject* pUnk, MonoComObject* *ppUnk);
2938         int (STDCALL *SByteIn)(MonoComObject* pUnk, char a);
2939         int (STDCALL *ByteIn)(MonoComObject* pUnk, unsigned char a);
2940         int (STDCALL *ShortIn)(MonoComObject* pUnk, short a);
2941         int (STDCALL *UShortIn)(MonoComObject* pUnk, unsigned short a);
2942         int (STDCALL *IntIn)(MonoComObject* pUnk, int a);
2943         int (STDCALL *UIntIn)(MonoComObject* pUnk, unsigned int a);
2944         int (STDCALL *LongIn)(MonoComObject* pUnk, gint64 a);
2945         int (STDCALL *ULongIn)(MonoComObject* pUnk, guint64 a);
2946         int (STDCALL *FloatIn)(MonoComObject* pUnk, float a);
2947         int (STDCALL *DoubleIn)(MonoComObject* pUnk, double a);
2948         int (STDCALL *ITestIn)(MonoComObject* pUnk, MonoComObject* pUnk2);
2949         int (STDCALL *ITestOut)(MonoComObject* pUnk, MonoComObject* *ppUnk);
2950 } MonoIUnknown;
2951
2952 struct MonoComObject
2953 {
2954         MonoIUnknown* vtbl;
2955         int m_ref;
2956 };
2957
2958 static GUID IID_ITest = {0, 0, 0, {0,0,0,0,0,0,0,1}};
2959 static GUID IID_IMonoUnknown = {0, 0, 0, {0xc0,0,0,0,0,0,0,0x46}};
2960 static GUID IID_IMonoDispatch = {0x00020400, 0, 0, {0xc0,0,0,0,0,0,0,0x46}};
2961
2962 LIBTEST_API int STDCALL
2963 MonoQueryInterface(MonoComObject* pUnk, gpointer riid, gpointer* ppv)
2964 {
2965
2966         *ppv = NULL;
2967         if (!memcmp(riid, &IID_IMonoUnknown, sizeof(GUID))) {
2968                 *ppv = pUnk;
2969                 return S_OK;
2970         }
2971         else if (!memcmp(riid, &IID_ITest, sizeof(GUID))) {
2972                 *ppv = pUnk;
2973                 return S_OK;
2974         }
2975         else if (!memcmp(riid, &IID_IMonoDispatch, sizeof(GUID))) {
2976                 *ppv = pUnk;
2977                 return S_OK;
2978         }
2979         return 0x80004002; //E_NOINTERFACE;
2980 }
2981
2982 LIBTEST_API int STDCALL 
2983 MonoAddRef(MonoComObject* pUnk)
2984 {
2985         return ++(pUnk->m_ref);
2986 }
2987
2988 LIBTEST_API int STDCALL 
2989 MonoRelease(MonoComObject* pUnk)
2990 {
2991         return --(pUnk->m_ref);
2992 }
2993
2994 LIBTEST_API int STDCALL 
2995 SByteIn(MonoComObject* pUnk, char a)
2996 {
2997         return S_OK;
2998 }
2999
3000 LIBTEST_API int STDCALL 
3001 ByteIn(MonoComObject* pUnk, unsigned char a)
3002 {
3003         return S_OK;
3004 }
3005
3006 LIBTEST_API int STDCALL 
3007 ShortIn(MonoComObject* pUnk, short a)
3008 {
3009         return S_OK;
3010 }
3011
3012 LIBTEST_API int STDCALL 
3013 UShortIn(MonoComObject* pUnk, unsigned short a)
3014 {
3015         return S_OK;
3016 }
3017
3018 LIBTEST_API int STDCALL 
3019 IntIn(MonoComObject* pUnk, int a)
3020 {
3021         return S_OK;
3022 }
3023
3024 LIBTEST_API int STDCALL 
3025 UIntIn(MonoComObject* pUnk, unsigned int a)
3026 {
3027         return S_OK;
3028 }
3029
3030 LIBTEST_API int STDCALL 
3031 LongIn(MonoComObject* pUnk, gint64 a)
3032 {
3033         return S_OK;
3034 }
3035
3036 LIBTEST_API int STDCALL 
3037 ULongIn(MonoComObject* pUnk, guint64 a)
3038 {
3039         return S_OK;
3040 }
3041
3042 LIBTEST_API int STDCALL 
3043 FloatIn(MonoComObject* pUnk, float a)
3044 {
3045         return S_OK;
3046 }
3047
3048 LIBTEST_API int STDCALL 
3049 DoubleIn(MonoComObject* pUnk, double a)
3050 {
3051         return S_OK;
3052 }
3053
3054 LIBTEST_API int STDCALL 
3055 ITestIn(MonoComObject* pUnk, MonoComObject *pUnk2)
3056 {
3057         return S_OK;
3058 }
3059
3060 LIBTEST_API int STDCALL 
3061 ITestOut(MonoComObject* pUnk, MonoComObject* *ppUnk)
3062 {
3063         return S_OK;
3064 }
3065
3066 LIBTEST_API int STDCALL 
3067 get_ITest(MonoComObject* pUnk, MonoComObject* *ppUnk)
3068 {
3069         return S_OK;
3070 }
3071
3072 static void create_com_object (MonoComObject** pOut)
3073 {
3074         *pOut = g_new0 (MonoComObject, 1);
3075         (*pOut)->vtbl = g_new0 (MonoIUnknown, 1);
3076
3077         (*pOut)->m_ref = 1;
3078         (*pOut)->vtbl->QueryInterface = MonoQueryInterface;
3079         (*pOut)->vtbl->AddRef = MonoAddRef;
3080         (*pOut)->vtbl->Release = MonoRelease;
3081         (*pOut)->vtbl->SByteIn = SByteIn;
3082         (*pOut)->vtbl->ByteIn = ByteIn;
3083         (*pOut)->vtbl->ShortIn = ShortIn;
3084         (*pOut)->vtbl->UShortIn = UShortIn;
3085         (*pOut)->vtbl->IntIn = IntIn;
3086         (*pOut)->vtbl->UIntIn = UIntIn;
3087         (*pOut)->vtbl->LongIn = LongIn;
3088         (*pOut)->vtbl->ULongIn = ULongIn;
3089         (*pOut)->vtbl->FloatIn = FloatIn;
3090         (*pOut)->vtbl->DoubleIn = DoubleIn;
3091         (*pOut)->vtbl->ITestIn = ITestIn;
3092         (*pOut)->vtbl->ITestOut = ITestOut;
3093         (*pOut)->vtbl->get_ITest = get_ITest;
3094 }
3095
3096 static MonoComObject* same_object = NULL;
3097
3098 LIBTEST_API int STDCALL 
3099 mono_test_marshal_com_object_create(MonoComObject* *pUnk)
3100 {
3101         create_com_object (pUnk);
3102
3103         if (!same_object)
3104                 same_object = *pUnk;
3105
3106         return 0;
3107 }
3108
3109 LIBTEST_API int STDCALL 
3110 mono_test_marshal_com_object_same(MonoComObject* *pUnk)
3111 {
3112         *pUnk = same_object;
3113
3114         return 0;
3115 }
3116
3117 LIBTEST_API int STDCALL 
3118 mono_test_marshal_com_object_destroy(MonoComObject *pUnk)
3119 {
3120         int ref = --(pUnk->m_ref);
3121         g_free(pUnk->vtbl);
3122         g_free(pUnk);
3123
3124         return ref;
3125 }
3126
3127 LIBTEST_API int STDCALL 
3128 mono_test_marshal_com_object_ref_count(MonoComObject *pUnk)
3129 {
3130         return pUnk->m_ref;
3131 }
3132
3133 LIBTEST_API int STDCALL 
3134 mono_test_marshal_ccw_itest (MonoComObject *pUnk)
3135 {
3136         int hr = 0;
3137         MonoComObject* pTest;
3138
3139         if (!pUnk)
3140                 return 1;
3141
3142         hr = pUnk->vtbl->SByteIn (pUnk, -100);
3143         if (hr != 0)
3144                 return 2;
3145         hr = pUnk->vtbl->ByteIn (pUnk, 100);
3146         if (hr != 0)
3147                 return 3;
3148         hr = pUnk->vtbl->ShortIn (pUnk, -100);
3149         if (hr != 0)
3150                 return 4;
3151         hr = pUnk->vtbl->UShortIn (pUnk, 100);
3152         if (hr != 0)
3153                 return 5;
3154         hr = pUnk->vtbl->IntIn (pUnk, -100);
3155         if (hr != 0)
3156                 return 6;
3157         hr = pUnk->vtbl->UIntIn (pUnk, 100);
3158         if (hr != 0)
3159                 return 7;
3160         hr = pUnk->vtbl->LongIn (pUnk, -100);
3161         if (hr != 0)
3162                 return 8;
3163         hr = pUnk->vtbl->ULongIn (pUnk, 100);
3164         if (hr != 0)
3165                 return 9;
3166         hr = pUnk->vtbl->FloatIn (pUnk, 3.14f);
3167         if (hr != 0)
3168                 return 10;
3169         hr = pUnk->vtbl->DoubleIn (pUnk, 3.14);
3170         if (hr != 0)
3171                 return 11;
3172         hr = pUnk->vtbl->ITestIn (pUnk, pUnk);
3173         if (hr != 0)
3174                 return 12;
3175         hr = pUnk->vtbl->ITestOut (pUnk, &pTest);
3176         if (hr != 0)
3177                 return 13;
3178
3179         return 0;
3180 }
3181
3182 /*
3183  * mono_method_get_unmanaged_thunk tests
3184  */
3185
3186 #if defined(__GNUC__) && ((defined(__i386__) && (defined(__linux__) || defined (__APPLE__)) || defined (__FreeBSD__)) || (defined(__ppc__) && defined(__APPLE__)))
3187 #define ALIGN(size) __attribute__ ((aligned(size)))
3188 #else
3189 #define ALIGN(size)
3190 #endif
3191
3192
3193 /* thunks.cs:TestStruct */
3194 typedef struct _TestStruct {
3195         int A;
3196         double B ALIGN(8);  /* align according to  mono's struct layout */
3197 } TestStruct;
3198
3199 /* Searches for mono symbols in all loaded modules */
3200 static gpointer
3201 lookup_mono_symbol (const char *symbol_name)
3202 {
3203         gpointer symbol;
3204         if (g_module_symbol (g_module_open (NULL, G_MODULE_BIND_LAZY), symbol_name, &symbol))
3205                 return symbol;
3206         else
3207                 return NULL;
3208 }
3209
3210 /**
3211  * test_method_thunk:
3212  *
3213  * @test_id: the test number
3214  * @test_method_handle: MonoMethod* of the C# test method
3215  * @create_object_method_handle: MonoMethod* of thunks.cs:Test.CreateObject
3216  */
3217 LIBTEST_API int STDCALL  
3218 test_method_thunk (int test_id, gpointer test_method_handle, gpointer create_object_method_handle)
3219 {
3220         gpointer (*mono_method_get_unmanaged_thunk)(gpointer)
3221                 = lookup_mono_symbol ("mono_method_get_unmanaged_thunk");
3222
3223         gpointer (*mono_string_new_wrapper)(const char *)
3224                 = lookup_mono_symbol ("mono_string_new_wrapper");
3225
3226         char* (*mono_string_to_utf8)(gpointer)
3227                 = lookup_mono_symbol ("mono_string_to_utf8");
3228
3229         gpointer (*mono_object_unbox)(gpointer)
3230                 = lookup_mono_symbol ("mono_object_unbox");
3231
3232         gpointer test_method, ex = NULL;
3233         gpointer (STDCALL *CreateObject)(gpointer*);
3234
3235
3236         if (!mono_method_get_unmanaged_thunk)
3237                 return 1;
3238
3239         test_method =  mono_method_get_unmanaged_thunk (test_method_handle);
3240         if (!test_method)
3241                 return 2;
3242
3243         CreateObject = mono_method_get_unmanaged_thunk (create_object_method_handle);
3244         if (!CreateObject)
3245                 return 3;
3246
3247
3248         switch (test_id) {
3249
3250         case 0: {
3251                 /* thunks.cs:Test.Test0 */
3252                 void (STDCALL *F)(gpointer*) = test_method;
3253                 F (&ex);
3254                 break;
3255         }
3256
3257         case 1: {
3258                 /* thunks.cs:Test.Test1 */
3259                 int (STDCALL *F)(gpointer*) = test_method;
3260                 if (F (&ex) != 42)
3261                         return 4;
3262                 break;
3263         }
3264
3265         case 2: {
3266                 /* thunks.cs:Test.Test2 */
3267                 gpointer (STDCALL *F)(gpointer, gpointer*) = test_method;
3268                 gpointer str = mono_string_new_wrapper ("foo");
3269                 if (str != F (str, &ex))
3270                         return 4;
3271                 break;
3272         }
3273
3274         case 3: {
3275                 /* thunks.cs:Test.Test3 */
3276                 gpointer (STDCALL *F)(gpointer, gpointer, gpointer*);
3277                 gpointer obj;
3278                 gpointer str;
3279
3280                 F = test_method;
3281                 obj = CreateObject (&ex);
3282                 str = mono_string_new_wrapper ("bar");
3283
3284                 if (str != F (obj, str, &ex))
3285                         return 4;
3286                 break;
3287         }
3288
3289         case 4: {
3290                 /* thunks.cs:Test.Test4 */
3291                 int (STDCALL *F)(gpointer, gpointer, int, gpointer*);
3292                 gpointer obj;
3293                 gpointer str;
3294
3295                 F = test_method;
3296                 obj = CreateObject (&ex);
3297                 str = mono_string_new_wrapper ("bar");
3298
3299                 if (42 != F (obj, str, 42, &ex))
3300                         return 4;
3301
3302                 break;
3303         }
3304
3305         case 5: {
3306                 /* thunks.cs:Test.Test5 */
3307                 int (STDCALL *F)(gpointer, gpointer, int, gpointer*);
3308                 gpointer obj;
3309                 gpointer str;
3310
3311                 F = test_method;
3312                 obj = CreateObject (&ex);
3313                 str = mono_string_new_wrapper ("bar");
3314
3315                 F (obj, str, 42, &ex);
3316                 if (!ex)
3317                     return 4;
3318
3319                 break;
3320         }
3321
3322         case 6: {
3323                 /* thunks.cs:Test.Test6 */
3324                 int (STDCALL *F)(gpointer, guint8, gint16, gint32, gint64, float, double,
3325                                  gpointer, gpointer*);
3326                 gpointer obj;
3327                 gpointer str = mono_string_new_wrapper ("Test6");
3328                 int res;
3329
3330                 F = test_method;
3331                 obj = CreateObject (&ex);
3332
3333                 res = F (obj, 254, 32700, -245378, 6789600, 3.1415, 3.1415, str, &ex);
3334                 if (ex)
3335                         return 4;
3336
3337                 if (!res)
3338                         return 5;
3339
3340                 break;
3341         }
3342
3343         case 7: {
3344                 /* thunks.cs:Test.Test7 */
3345                 gint64 (STDCALL *F)(gpointer*) = test_method;
3346                 if (F (&ex) != G_MAXINT64)
3347                         return 4;
3348                 break;
3349         }
3350
3351         case 8: {
3352                 /* thunks.cs:Test.Test8 */
3353                 void (STDCALL *F)(guint8*, gint16*, gint32*, gint64*, float*, double*,
3354                                  gpointer*, gpointer*);
3355
3356                 guint8 a1;
3357                 gint16 a2;
3358                 gint32 a3;
3359                 gint64 a4;
3360                 float a5;
3361                 double a6;
3362                 gpointer a7;
3363
3364                 F = test_method;
3365
3366                 F (&a1, &a2, &a3, &a4, &a5, &a6, &a7, &ex);
3367                 if (ex)
3368                         return 4;
3369
3370                 if (!(a1 == 254 &&
3371                       a2 == 32700 &&
3372                       a3 == -245378 &&
3373                       a4 == 6789600 &&
3374                       (fabs (a5 - 3.1415) < 0.001) &&
3375                       (fabs (a6 - 3.1415) < 0.001) &&
3376                       strcmp (mono_string_to_utf8 (a7), "Test8") == 0))
3377                         return 5;
3378
3379                 break;
3380         }
3381
3382         case 9: {
3383                 /* thunks.cs:Test.Test9 */
3384                 void (STDCALL *F)(guint8*, gint16*, gint32*, gint64*, float*, double*,
3385                                  gpointer*, gpointer*);
3386
3387                 guint8 a1;
3388                 gint16 a2;
3389                 gint32 a3;
3390                 gint64 a4;
3391                 float a5;
3392                 double a6;
3393                 gpointer a7;
3394
3395                 F = test_method;
3396
3397                 F (&a1, &a2, &a3, &a4, &a5, &a6, &a7, &ex);
3398                 if (!ex)
3399                         return 4;
3400
3401                 break;
3402         }
3403
3404         case 10: {
3405                 /* thunks.cs:Test.Test10 */
3406                 void (STDCALL *F)(gpointer*, gpointer*);
3407
3408                 gpointer obj1, obj2;
3409
3410                 obj1 = obj2 = CreateObject (&ex);
3411                 if (ex)
3412                         return 4;
3413
3414                 F = test_method;
3415
3416                 F (&obj1, &ex);
3417                 if (ex)
3418                         return 5;
3419
3420                 if (obj1 == obj2)
3421                         return 6;
3422
3423                 break;
3424         }
3425
3426         case 100: {
3427                 /* thunks.cs:TestStruct.Test0 */
3428                 int (STDCALL *F)(gpointer*, gpointer*);
3429
3430                 gpointer obj;
3431                 TestStruct *a1;
3432                 int res;
3433
3434                 obj = CreateObject (&ex);
3435                 if (ex)
3436                         return 4;
3437
3438                 if (!obj)
3439                         return 5;
3440
3441                 a1 = mono_object_unbox (obj);
3442                 if (!a1)
3443                         return 6;
3444
3445                 a1->A = 42;
3446                 a1->B = 3.1415;
3447
3448                 F = test_method;
3449
3450                 res = F (obj, &ex);
3451                 if (ex)
3452                         return 7;
3453
3454                 if (!res)
3455                         return 8;
3456
3457                 /* check whether the call was really by value */
3458                 if (a1->A != 42 || a1->B != 3.1415)
3459                         return 9;
3460
3461                 break;
3462         }
3463
3464         case 101: {
3465                 /* thunks.cs:TestStruct.Test1 */
3466                 void (STDCALL *F)(gpointer, gpointer*);
3467
3468                 TestStruct *a1;
3469                 gpointer obj;
3470
3471                 obj = CreateObject (&ex);
3472                 if (ex)
3473                         return 4;
3474
3475                 if (!obj)
3476                         return 5;
3477
3478                 a1 = mono_object_unbox (obj);
3479                 if (!a1)
3480                         return 6;
3481
3482                 F = test_method;
3483
3484                 F (obj, &ex);
3485                 if (ex)
3486                         return 7;
3487
3488                 if (a1->A != 42)
3489                         return 8;
3490
3491                 if (!fabs (a1->B - 3.1415) < 0.001)
3492                         return 9;
3493
3494                 break;
3495         }
3496
3497         case 102: {
3498                 /* thunks.cs:TestStruct.Test2 */
3499                 gpointer (STDCALL *F)(gpointer*);
3500
3501                 TestStruct *a1;
3502                 gpointer obj;
3503
3504                 F = test_method;
3505
3506                 obj = F (&ex);
3507                 if (ex)
3508                         return 4;
3509
3510                 if (!obj)
3511                         return 5;
3512
3513                 a1 = mono_object_unbox (obj);
3514
3515                 if (a1->A != 42)
3516                         return 5;
3517
3518                 if (!fabs (a1->B - 3.1415) < 0.001)
3519                         return 6;
3520
3521                 break;
3522         }
3523
3524         case 103: {
3525                 /* thunks.cs:TestStruct.Test3 */
3526                 void (STDCALL *F)(gpointer, gpointer*);
3527
3528                 TestStruct *a1;
3529                 gpointer obj;
3530
3531                 obj = CreateObject (&ex);
3532                 if (ex)
3533                         return 4;
3534
3535                 if (!obj)
3536                         return 5;
3537                 
3538                 a1 = mono_object_unbox (obj);
3539
3540                 if (!a1)
3541                         return 6;
3542
3543                 a1->A = 42;
3544                 a1->B = 3.1415;
3545
3546                 F = test_method;
3547
3548                 F (obj, &ex);
3549                 if (ex)
3550                         return 4;
3551
3552                 if (a1->A != 1)
3553                         return 5;
3554
3555                 if (a1->B != 17)
3556                         return 6;
3557
3558                 break;
3559         }
3560
3561         default:
3562                 return 9;
3563
3564         }
3565
3566         return 0;
3567 }
3568
3569 typedef struct 
3570 {
3571         char a;
3572 } winx64_struct1;
3573
3574 LIBTEST_API int STDCALL  
3575 mono_test_Winx64_struct1_in (winx64_struct1 var)
3576 {
3577         if (var.a != 123)
3578                 return 1;
3579         return 0;
3580 }
3581
3582 typedef struct
3583 {
3584         char a;
3585         char b;
3586 } winx64_struct2;
3587
3588 LIBTEST_API int STDCALL  
3589 mono_test_Winx64_struct2_in (winx64_struct2 var)
3590 {
3591         if (var.a != 4)
3592                 return 1;
3593         if (var.b != 5)
3594                 return 2;
3595         return 0;
3596 }
3597
3598
3599 typedef struct
3600 {
3601         char a;
3602         char b;
3603         short c;
3604 } winx64_struct3;
3605
3606 LIBTEST_API int STDCALL  
3607 mono_test_Winx64_struct3_in (winx64_struct3 var)
3608 {
3609         if (var.a != 4)
3610                 return 1;
3611         if (var.b != 5)
3612                 return 2;
3613         if (var.c != 0x1234)
3614                 return 3;
3615         return 0;
3616 }
3617
3618 typedef struct
3619 {
3620         char a;
3621         char b;
3622         short c;
3623         unsigned int d;
3624 } winx64_struct4;
3625
3626 LIBTEST_API int STDCALL  
3627 mono_test_Winx64_struct4_in (winx64_struct4 var)
3628 {
3629         if (var.a != 4)
3630                 return 1;
3631         if (var.b != 5)
3632                 return 2;
3633         if (var.c != 0x1234)
3634                 return 3;
3635         if (var.d != 0x87654321)
3636                 return 4;
3637         return 0;
3638 }
3639
3640 typedef struct
3641 {
3642         char a;
3643         char b;
3644         char c;
3645 } winx64_struct5;
3646
3647 LIBTEST_API int STDCALL  
3648 mono_test_Winx64_struct5_in (winx64_struct5 var)
3649 {
3650         if (var.a != 4)
3651                 return 1;
3652         if (var.b != 5)
3653                 return 2;
3654         if (var.c != 6)
3655                 return 3;
3656         return 0;
3657 }
3658
3659 typedef struct
3660 {
3661         winx64_struct1 a;
3662         short b;
3663         char c;
3664 } winx64_struct6;
3665
3666 LIBTEST_API int STDCALL  
3667 mono_test_Winx64_struct6_in (winx64_struct6 var)
3668 {
3669         if (var.a.a != 4)
3670                 return 1;
3671         if (var.b != 5)
3672                 return 2;
3673         if (var.c != 6)
3674                 return 3;
3675         return 0;
3676 }
3677
3678 LIBTEST_API int STDCALL  
3679 mono_test_Winx64_structs_in1 (winx64_struct1 var1,
3680                          winx64_struct2 var2,
3681                          winx64_struct3 var3,
3682                          winx64_struct4 var4)
3683 {
3684         if (var1.a != 123)
3685                 return 1;
3686         
3687         if (var2.a != 4)
3688                 return 2;
3689         if (var2.b != 5)
3690                 return 3;
3691         
3692         if (var3.a != 4)
3693                 return 4;
3694         if (var3.b != 5)
3695                 return 2;
3696         if (var3.c != 0x1234)
3697                 return 5;
3698         
3699         if (var4.a != 4)
3700                 return 6;
3701         if (var4.b != 5)
3702                 return 7;
3703         if (var4.c != 0x1234)
3704                 return 8;
3705         if (var4.d != 0x87654321)
3706                 return 9;
3707         return 0;
3708 }
3709
3710 LIBTEST_API int STDCALL  
3711 mono_test_Winx64_structs_in2 (winx64_struct1 var1,
3712                          winx64_struct1 var2,
3713                          winx64_struct1 var3,
3714                          winx64_struct1 var4,
3715                          winx64_struct1 var5)
3716 {
3717         if (var1.a != 1)
3718                 return 1;
3719         if (var2.a != 2)
3720                 return 2;
3721         if (var3.a != 3)
3722                 return 3;
3723         if (var4.a != 4)
3724                 return 4;
3725         if (var5.a != 5)
3726                 return 5;
3727         
3728         return 0;
3729 }
3730
3731 LIBTEST_API int STDCALL  
3732 mono_test_Winx64_structs_in3 (winx64_struct1 var1,
3733                          winx64_struct5 var2,
3734                          winx64_struct1 var3,
3735                          winx64_struct5 var4,
3736                          winx64_struct1 var5,
3737                          winx64_struct5 var6)
3738 {
3739         if (var1.a != 1)
3740                 return 1;
3741         
3742         if (var2.a != 2)
3743                 return 2;
3744         if (var2.b != 3)
3745                 return 2;
3746         if (var2.c != 4)
3747                 return 4;
3748         
3749         if (var3.a != 5)
3750                 return 5;
3751         
3752         if (var4.a != 6)
3753                 return 6;
3754         if (var4.b != 7)
3755                 return 7;
3756         if (var4.c != 8)
3757                 return 8;
3758         
3759         if (var5.a != 9)
3760                 return 9;
3761
3762         if (var6.a != 10)
3763                 return 10;
3764         if (var6.b != 11)
3765                 return 11;
3766         if (var6.c != 12)
3767                 return 12;
3768         
3769         return 0;
3770 }
3771
3772 LIBTEST_API winx64_struct1 STDCALL  
3773 mono_test_Winx64_struct1_ret (void)
3774 {
3775         winx64_struct1 ret;
3776         ret.a = 123;
3777         return ret;
3778 }
3779
3780 LIBTEST_API winx64_struct2 STDCALL  
3781 mono_test_Winx64_struct2_ret (void)
3782 {
3783         winx64_struct2 ret;
3784         ret.a = 4;
3785         ret.b = 5;
3786         return ret;
3787 }
3788
3789 LIBTEST_API winx64_struct3 STDCALL  
3790 mono_test_Winx64_struct3_ret (void)
3791 {
3792         winx64_struct3 ret;
3793         ret.a = 4;
3794         ret.b = 5;
3795         ret.c = 0x1234;
3796         return ret;
3797 }
3798
3799 LIBTEST_API winx64_struct4 STDCALL  
3800 mono_test_Winx64_struct4_ret (void)
3801 {
3802         winx64_struct4 ret;
3803         ret.a = 4;
3804         ret.b = 5;
3805         ret.c = 0x1234;
3806         ret.d = 0x87654321;
3807         return ret;
3808 }
3809
3810 LIBTEST_API winx64_struct5 STDCALL  
3811 mono_test_Winx64_struct5_ret (void)
3812 {
3813         winx64_struct5 ret;
3814         ret.a = 4;
3815         ret.b = 5;
3816         ret.c = 6;
3817         return ret;
3818 }
3819
3820 LIBTEST_API winx64_struct1 STDCALL  
3821 mono_test_Winx64_struct1_ret_5_args (char a, char b, char c, char d, char e)
3822 {
3823         winx64_struct1 ret;
3824         ret.a = a + b + c + d + e;
3825         return ret;
3826 }
3827
3828 LIBTEST_API winx64_struct5 STDCALL
3829 mono_test_Winx64_struct5_ret6_args (char a, char b, char c, char d, char e)
3830 {
3831         winx64_struct5 ret;
3832         ret.a = a + b;
3833         ret.b = c + d;
3834         ret.c = e;
3835         return ret;
3836 }
3837
3838 typedef struct
3839 {
3840         float a;
3841         float b;
3842 } winx64_floatStruct;
3843
3844 LIBTEST_API int STDCALL  
3845 mono_test_Winx64_floatStruct (winx64_floatStruct a)
3846 {
3847         if (a.a > 5.6 || a.a < 5.4)
3848                 return 1;
3849
3850         if (a.b > 9.6 || a.b < 9.4)
3851                 return 2;
3852         
3853         return 0;
3854 }
3855
3856 typedef struct
3857 {
3858         double a;
3859 } winx64_doubleStruct;
3860
3861 LIBTEST_API int STDCALL  
3862 mono_test_Winx64_doubleStruct (winx64_doubleStruct a)
3863 {
3864         if (a.a > 5.6 || a.a < 5.4)
3865                 return 1;
3866         
3867         return 0;
3868 }
3869
3870 typedef int (STDCALL *managed_struct1_delegate) (winx64_struct1 a);
3871
3872 LIBTEST_API int STDCALL 
3873 mono_test_managed_Winx64_struct1_in(managed_struct1_delegate func)
3874 {
3875         winx64_struct1 val;
3876         val.a = 5;
3877         return func (val);
3878 }
3879
3880 typedef int (STDCALL *managed_struct5_delegate) (winx64_struct5 a);
3881
3882 LIBTEST_API int STDCALL 
3883 mono_test_managed_Winx64_struct5_in(managed_struct5_delegate func)
3884 {
3885         winx64_struct5 val;
3886         val.a = 5;
3887         val.b = 0x10;
3888         val.c = 0x99;
3889         return func (val);
3890 }
3891
3892 typedef int (STDCALL *managed_struct1_struct5_delegate) (winx64_struct1 a, winx64_struct5 b,
3893                                                          winx64_struct1 c, winx64_struct5 d,
3894                                                          winx64_struct1 e, winx64_struct5 f);
3895
3896 LIBTEST_API int STDCALL 
3897 mono_test_managed_Winx64_struct1_struct5_in(managed_struct1_struct5_delegate func)
3898 {
3899         winx64_struct1 a, c, e;
3900         winx64_struct5 b, d, f;
3901         a.a = 1;
3902         b.a = 2; b.b = 3; b.c = 4;
3903         c.a = 5;
3904         d.a = 6; d.b = 7; d.c = 8;
3905         e.a = 9;
3906         f.a = 10; f.b = 11; f.c = 12;
3907
3908         return func (a, b, c, d, e, f);
3909 }
3910
3911 typedef winx64_struct1 (STDCALL *managed_struct1_ret_delegate) (void);
3912
3913 LIBTEST_API int STDCALL 
3914 mono_test_Winx64_struct1_ret_managed (managed_struct1_ret_delegate func)
3915 {
3916         winx64_struct1 ret;
3917
3918         ret = func ();
3919
3920         if (ret.a != 0x45)
3921                 return 1;
3922         
3923         return 0;
3924 }
3925
3926 typedef winx64_struct5 (STDCALL *managed_struct5_ret_delegate) (void);
3927
3928 LIBTEST_API int STDCALL 
3929 mono_test_Winx64_struct5_ret_managed (managed_struct5_ret_delegate func)
3930 {
3931         winx64_struct5 ret;
3932
3933         ret = func ();
3934
3935         if (ret.a != 0x12)
3936                 return 1;
3937         if (ret.b != 0x34)
3938                 return 2;
3939         if (ret.c != 0x56)
3940                 return 3;
3941         
3942         return 0;
3943 }
3944
3945 LIBTEST_API int STDCALL 
3946 mono_test_marshal_bool_in (int arg, unsigned int expected, unsigned int bDefaultMarsh, unsigned int bBoolCustMarsh,
3947                            char bI1CustMarsh, unsigned char bU1CustMarsh, unsigned short bVBCustMarsh)
3948 {
3949         switch (arg) {
3950         case 1: 
3951                 if (bDefaultMarsh != expected)
3952                         return 1;
3953                 break;
3954         case 2: 
3955                 if (bBoolCustMarsh != expected)
3956                         return 2;
3957                 break;
3958         case 3: 
3959                 if (bI1CustMarsh != expected)
3960                         return 3;
3961                 break;
3962         case 4: 
3963                 if (bU1CustMarsh != expected)
3964                         return 4;
3965                 break;
3966         case 5: 
3967                 if (bVBCustMarsh != expected)
3968                         return 5;
3969                 break;
3970         default:
3971                 return 999;             
3972         }
3973         return 0;
3974 }
3975
3976 LIBTEST_API int STDCALL 
3977 mono_test_marshal_bool_out (int arg, unsigned int testVal, unsigned int* bDefaultMarsh, unsigned int* bBoolCustMarsh,
3978                            char* bI1CustMarsh, unsigned char* bU1CustMarsh, unsigned short* bVBCustMarsh)
3979 {
3980         switch (arg) {
3981         case 1: 
3982                 if (!bDefaultMarsh)
3983                         return 1;
3984                 *bDefaultMarsh = testVal;
3985                 break;  
3986         case 2: 
3987                 if (!bBoolCustMarsh)
3988                         return 2;
3989                 *bBoolCustMarsh = testVal;
3990                 break;  
3991         case 3: 
3992                 if (!bI1CustMarsh)
3993                         return 3;
3994                 *bI1CustMarsh = (char)testVal;
3995                 break;  
3996         case 4: 
3997                 if (!bU1CustMarsh)
3998                         return 4;
3999                 *bU1CustMarsh = (unsigned char)testVal;
4000                 break;  
4001         case 5: 
4002                 if (!bVBCustMarsh)
4003                         return 5;
4004                 *bVBCustMarsh = (unsigned short)testVal;
4005                 break;  
4006         default:
4007                 return 999;
4008         }
4009         return 0;
4010 }
4011
4012 LIBTEST_API int STDCALL 
4013 mono_test_marshal_bool_ref (int arg, unsigned int expected, unsigned int testVal, unsigned int* bDefaultMarsh,
4014                             unsigned int* bBoolCustMarsh, char* bI1CustMarsh, unsigned char* bU1CustMarsh, 
4015                             unsigned short* bVBCustMarsh)
4016 {
4017         switch (arg) {
4018         case 1: 
4019                 if (!bDefaultMarsh)
4020                         return 1;
4021                 if (*bDefaultMarsh != expected)
4022                         return 2;
4023                 *bDefaultMarsh = testVal;
4024                 break;
4025         case 2: 
4026                 if (!bBoolCustMarsh)
4027                         return 3;
4028                 if (*bBoolCustMarsh != expected)
4029                         return 4;
4030                 *bBoolCustMarsh = testVal;
4031                 break;
4032         case 3: 
4033                 if (!bI1CustMarsh)
4034                         return 5;
4035                 if (*bI1CustMarsh != expected)
4036                         return 6;
4037                 *bI1CustMarsh = (char)testVal;
4038                 break;
4039         case 4: 
4040                 if (!bU1CustMarsh)
4041                         return 7;
4042                 if (*bU1CustMarsh != expected)
4043                         return 8;
4044                 *bU1CustMarsh = (unsigned char)testVal;
4045                 break;
4046         case 5: 
4047                 if (!bVBCustMarsh)
4048                         return 9;
4049                 if (*bVBCustMarsh != expected)
4050                         return 10;
4051                 *bVBCustMarsh = (unsigned short)testVal;
4052                 break;
4053         default:
4054                 return 999;             
4055         }
4056         return 0;
4057 }
4058
4059
4060 typedef int (STDCALL *MarshalBoolInDelegate) (int arg, unsigned int expected, unsigned int bDefaultMarsh,
4061         unsigned int bBoolCustMarsh, char bI1CustMarsh, unsigned char bU1CustMarsh, unsigned short bVBCustMarsh);
4062
4063 LIBTEST_API int STDCALL 
4064 mono_test_managed_marshal_bool_in (int arg, unsigned int expected, unsigned int testVal, MarshalBoolInDelegate pfcn)
4065 {
4066         if (!pfcn)
4067                 return 0x9900;
4068
4069         switch (arg) {
4070         case 1:
4071                 return pfcn (arg, expected, testVal, 0, 0, 0, 0);
4072         case 2:
4073                 return pfcn (arg, expected, 0, testVal,  0, 0, 0);
4074         case 3:
4075                 return pfcn (arg, expected, 0, 0, testVal, 0, 0);
4076         case 4:
4077                 return pfcn (arg, expected, 0, 0, 0, testVal, 0);
4078         case 5:
4079                 return pfcn (arg, expected, 0, 0, 0, 0, testVal);
4080         default:
4081                 return 0x9800;
4082         }
4083
4084         return 0;
4085 }
4086
4087 typedef int (STDCALL *MarshalBoolOutDelegate) (int arg, unsigned int expected, unsigned int* bDefaultMarsh,
4088         unsigned int* bBoolCustMarsh, char* bI1CustMarsh, unsigned char* bU1CustMarsh, unsigned short* bVBCustMarsh);
4089
4090 LIBTEST_API int STDCALL 
4091 mono_test_managed_marshal_bool_out (int arg, unsigned int expected, unsigned int testVal, MarshalBoolOutDelegate pfcn)
4092 {
4093         int ret;
4094         unsigned int lDefaultMarsh, lBoolCustMarsh;
4095         char lI1CustMarsh = 0;
4096         unsigned char lU1CustMarsh = 0;
4097         unsigned short lVBCustMarsh = 0;
4098         lDefaultMarsh = lBoolCustMarsh = 0;
4099
4100         if (!pfcn)
4101                 return 0x9900;
4102
4103         switch (arg) {
4104         case 1: {
4105                 unsigned int ltVal = 0;
4106                 ret = pfcn (arg, testVal, &ltVal, &lBoolCustMarsh, &lI1CustMarsh, &lU1CustMarsh, &lVBCustMarsh);
4107                 if (ret)
4108                         return 0x0100 + ret;
4109                 if (expected != ltVal)
4110                         return 0x0200;
4111                 break;
4112         }
4113         case 2: {
4114                 unsigned int ltVal = 0;
4115                 ret = pfcn (arg, testVal, &lDefaultMarsh, &ltVal, &lI1CustMarsh, &lU1CustMarsh, &lVBCustMarsh);
4116                 if (ret)
4117                         return 0x0300 + ret;
4118                 if (expected != ltVal)
4119                         return 0x0400;
4120                 break;
4121         }
4122         case 3: {
4123                 char ltVal = 0;
4124                 ret = pfcn (arg, testVal, &lDefaultMarsh, &lBoolCustMarsh, &ltVal, &lU1CustMarsh, &lVBCustMarsh);
4125                 if (ret)
4126                         return 0x0500 + ret;
4127                 if (expected != ltVal)
4128                         return 0x0600;
4129                 break;
4130         }
4131         case 4: {
4132                 unsigned char ltVal = 0;
4133                 ret = pfcn (arg, testVal, &lDefaultMarsh, &lBoolCustMarsh, &lI1CustMarsh, &ltVal, &lVBCustMarsh);
4134                 if (ret)
4135                         return 0x0700 + ret;
4136                 if (expected != ltVal)
4137                         return 0x0800;
4138                 break;
4139         }
4140         case 5: {
4141                 unsigned short ltVal = 0;
4142                 ret = pfcn (arg, testVal, &lDefaultMarsh, &lBoolCustMarsh, &lI1CustMarsh, &lU1CustMarsh, &ltVal);
4143                 if (ret)
4144                         return 0x0900 + ret;
4145                 if (expected != ltVal)
4146                         return 0x1000;
4147                 break;
4148         }
4149         default:
4150                 return 0x9800;
4151         }
4152
4153         return 0;
4154 }
4155
4156 typedef int (STDCALL *MarshalBoolRefDelegate) (int arg, unsigned int expected, unsigned int testVal, unsigned int* bDefaultMarsh,
4157         unsigned int* bBoolCustMarsh, char* bI1CustMarsh, unsigned char* bU1CustMarsh, unsigned short* bVBCustMarsh);
4158
4159 LIBTEST_API int STDCALL 
4160 mono_test_managed_marshal_bool_ref (int arg, unsigned int expected, unsigned int testVal, unsigned int outExpected,
4161                                     unsigned int outTestVal, MarshalBoolRefDelegate pfcn)
4162 {
4163         int ret;
4164         unsigned int lDefaultMarsh, lBoolCustMarsh;
4165         char lI1CustMarsh = 0;
4166         unsigned char lU1CustMarsh = 0;
4167         unsigned short lVBCustMarsh = 0;
4168         lDefaultMarsh = lBoolCustMarsh = 0;
4169
4170         if (!pfcn)
4171                 return 0x9900;
4172
4173         switch (arg) {
4174         case 1:
4175         {
4176                 unsigned int ltestVal = testVal;
4177                 ret = pfcn (arg, expected, outTestVal, &ltestVal, &lBoolCustMarsh, &lI1CustMarsh, &lU1CustMarsh, &lVBCustMarsh);
4178                 if (ret)
4179                         return 0x0100 + ret;
4180                 if (outExpected != ltestVal)
4181                         return 0x0200;
4182                 break;
4183         }
4184         case 2:
4185         {
4186                 unsigned int ltestVal = testVal;
4187                 ret = pfcn (arg, expected, outTestVal, &lDefaultMarsh, &ltestVal, &lI1CustMarsh, &lU1CustMarsh, &lVBCustMarsh);
4188                 if (ret)
4189                         return 0x0300 + ret;
4190                 if (outExpected != ltestVal)
4191                         return 0x0400;
4192                 break;
4193         }
4194         case 3:
4195         {
4196                 char ltestVal = testVal;
4197                 ret = pfcn (arg, expected, outTestVal, &lDefaultMarsh, &lBoolCustMarsh, &ltestVal, &lU1CustMarsh, &lVBCustMarsh);
4198                 if (ret)
4199                         return 0x0500 + ret;
4200                 if (outExpected != ltestVal)
4201                         return 0x0600;
4202                 break;
4203         }
4204         case 4:
4205         {
4206                 unsigned char ltestVal = testVal;
4207                 ret = pfcn (arg, expected, outTestVal, &lDefaultMarsh, &lBoolCustMarsh, &lI1CustMarsh, &ltestVal, &lVBCustMarsh);
4208                 if (ret)
4209                         return 0x0700 + ret;
4210                 if (outExpected != ltestVal)
4211                         return 0x0800;
4212                 break;
4213         }
4214         case 5:
4215         {
4216                 unsigned short ltestVal = testVal;
4217                 ret = pfcn (arg, expected, outTestVal, &lDefaultMarsh, &lBoolCustMarsh, &lI1CustMarsh, &lU1CustMarsh, &ltestVal);
4218                 if (ret)
4219                         return 0x0900 + ret;
4220                 if (outExpected != ltestVal)
4221                         return 0x1000;
4222                 break;
4223         }
4224         default:
4225                 return 0x9800;
4226         }
4227
4228         return 0;
4229 }
4230
4231 #ifdef WIN32
4232
4233 LIBTEST_API int STDCALL 
4234 mono_test_marshal_variant_out_safearray_1dim_vt_bstr_empty (SAFEARRAY** safearray)
4235 {
4236         /* Create an empty one-dimensional array of variants */
4237         SAFEARRAY *pSA;
4238         SAFEARRAYBOUND dimensions [1];
4239
4240         dimensions [0].lLbound = 0;
4241         dimensions [0].cElements = 0;
4242
4243         pSA= SafeArrayCreate (VT_VARIANT, 1, dimensions);
4244         *safearray = pSA;
4245         return S_OK;
4246 }
4247
4248 LIBTEST_API int STDCALL 
4249 mono_test_marshal_variant_out_safearray_1dim_vt_bstr (SAFEARRAY** safearray)
4250 {
4251         /* Create a one-dimensional array of 10 variants filled with "0" to "9" */
4252         SAFEARRAY *pSA;
4253         SAFEARRAYBOUND dimensions [1];
4254         long i;
4255         gchar buffer [20];
4256         HRESULT hr = S_OK;
4257         long indices [1];
4258
4259         dimensions [0].lLbound = 0;
4260         dimensions [0].cElements = 10;
4261
4262         pSA= SafeArrayCreate (VT_VARIANT, 1, dimensions);
4263         for (i= dimensions [0].lLbound; i< (dimensions [0].cElements + dimensions [0].lLbound); i++) {
4264                 VARIANT vOut;
4265                 VariantInit (&vOut);
4266                 vOut.vt = VT_BSTR;
4267                 _ltoa (i,buffer,10);
4268                 vOut.bstrVal= marshal_bstr_alloc (buffer);
4269                 indices [0] = i;
4270                 if ((hr = SafeArrayPutElement (pSA, indices, &vOut)) != S_OK) {
4271                         VariantClear (&vOut);
4272                         SafeArrayDestroy (pSA);
4273                         return hr;
4274                 }
4275                 VariantClear (&vOut);
4276         }
4277         *safearray = pSA;
4278         return hr;
4279 }
4280
4281 LIBTEST_API int STDCALL 
4282 mono_test_marshal_variant_out_safearray_2dim_vt_int (SAFEARRAY** safearray)
4283 {
4284         /* Create a two-dimensional array of 4x3 variants filled with 11, 12, 13, etc. */
4285         SAFEARRAY *pSA;
4286         SAFEARRAYBOUND dimensions [2];
4287         long i, j;
4288         HRESULT hr = S_OK;
4289         long indices [2];
4290
4291         dimensions [0].lLbound = 0;
4292         dimensions [0].cElements = 4;
4293         dimensions [1].lLbound = 0;
4294         dimensions [1].cElements = 3;
4295
4296         pSA= SafeArrayCreate(VT_VARIANT, 2, dimensions);
4297         for (i= dimensions [0].lLbound; i< (dimensions [0].cElements + dimensions [0].lLbound); i++) {
4298                 for (j= dimensions [1].lLbound; j< (dimensions [1].cElements + dimensions [1].lLbound); j++) {
4299                         VARIANT vOut;
4300                         VariantInit (&vOut);
4301                         vOut.vt = VT_I4;
4302                         vOut.intVal = (i+1)*10+(j+1);
4303                         indices [0] = i;
4304                         indices [1] = j;
4305                         if ((hr = SafeArrayPutElement (pSA, indices, &vOut)) != S_OK) {
4306                                 VariantClear (&vOut);
4307                                 SafeArrayDestroy (pSA);
4308                                 return hr;
4309                         }
4310                         VariantClear (&vOut);  // does a deep destroy of source VARIANT 
4311                 }
4312         }
4313         *safearray = pSA;
4314         return hr;
4315 }
4316
4317 LIBTEST_API int STDCALL 
4318 mono_test_marshal_variant_out_safearray_4dim_vt_int (SAFEARRAY** safearray)
4319 {
4320         /* Create a four-dimensional array of 10x3x6x7 variants filled with their indices */
4321         /* Also use non zero lower bounds                                                 */
4322         SAFEARRAY *pSA;
4323         SAFEARRAYBOUND dimensions [4];
4324         long i;
4325         HRESULT hr = S_OK;
4326         VARIANT *pData;
4327
4328         dimensions [0].lLbound = 15;
4329         dimensions [0].cElements = 10;
4330         dimensions [1].lLbound = 20;
4331         dimensions [1].cElements = 3;
4332         dimensions [2].lLbound = 5;
4333         dimensions [2].cElements = 6;
4334         dimensions [3].lLbound = 12;
4335         dimensions [3].cElements = 7;
4336
4337         pSA= SafeArrayCreate (VT_VARIANT, 4, dimensions);
4338
4339         SafeArrayAccessData (pSA, (void **)&pData);
4340
4341         for (i= 0; i< 10*3*6*7; i++) {
4342                 VariantInit(&pData [i]);
4343                 pData [i].vt = VT_I4;
4344                 pData [i].intVal = i;
4345         }
4346         SafeArrayUnaccessData(pSA);
4347         *safearray = pSA;
4348         return hr;
4349 }
4350
4351 #endif
4352
4353