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