Merge pull request #1612 from esdrubal/socketsh
[mono.git] / mono / tests / libtest.c
1 #include <config.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <glib.h>
6 #include <gmodule.h>
7 #include <errno.h>
8 #include <time.h>
9 #include <math.h>
10
11 #ifdef WIN32
12 #include <windows.h>
13 #include "initguid.h"
14 #else
15 #include <pthread.h>
16 #endif
17
18 #ifdef WIN32
19 #define STDCALL __stdcall
20 #else
21 #define STDCALL
22 #endif
23
24 #ifdef __GNUC__
25 #pragma GCC diagnostic ignored "-Wmissing-prototypes"
26 #endif
27
28 #ifdef WIN32
29 extern __declspec(dllimport) void __stdcall CoTaskMemFree(void *ptr);
30 #endif
31
32 typedef int (STDCALL *SimpleDelegate) (int a);
33
34 #if defined(WIN32) && defined (_MSC_VER)
35 #define LIBTEST_API __declspec(dllexport)
36 #elif defined(__GNUC__)
37 #define LIBTEST_API  __attribute__ ((visibility ("default")))
38 #else
39 #define LIBTEST_API
40 #endif
41
42 static void marshal_free (void *ptr)
43 {
44 #ifdef WIN32
45         CoTaskMemFree (ptr);
46 #else
47         g_free (ptr);
48 #endif
49 }
50
51 static void* marshal_alloc (gsize size)
52 {
53 #ifdef WIN32
54         return CoTaskMemAlloc (size);
55 #else
56         return g_malloc (size);
57 #endif
58 }
59
60 static void* marshal_alloc0 (gsize size)
61 {
62 #ifdef WIN32
63         void* ptr = CoTaskMemAlloc (size);
64         memset(ptr, 0, size);
65         return ptr;
66 #else
67         return g_malloc0 (size);
68 #endif
69 }
70
71 static char* marshal_strdup (const char *str)
72 {
73 #ifdef WIN32
74         int len;
75         char *buf;
76
77         if (!str)
78                 return NULL;
79
80         len = strlen (str);
81         buf = (char *) CoTaskMemAlloc (len + 1);
82         return strcpy (buf, str);
83 #else
84         return g_strdup (str);
85 #endif
86 }
87
88 static gunichar2* marshal_bstr_alloc(const gchar* str)
89 {
90 #ifdef WIN32
91         gunichar2* ret = NULL;
92         gunichar2* temp = NULL;
93         temp = g_utf8_to_utf16 (str, -1, NULL, NULL, NULL);
94         ret = SysAllocString (temp);
95         g_free (temp);
96         return ret;
97 #else
98         gchar* ret = NULL;
99         int slen = strlen (str);
100         gunichar2* temp;
101         /* allocate len + 1 utf16 characters plus 4 byte integer for length*/
102         ret = g_malloc ((slen + 1) * sizeof(gunichar2) + sizeof(guint32));
103         if (ret == NULL)
104                 return NULL;
105         temp = g_utf8_to_utf16 (str, -1, NULL, NULL, NULL);
106         memcpy (ret + sizeof(guint32), temp, slen * sizeof(gunichar2));
107         * ((guint32 *) ret) = slen * sizeof(gunichar2);
108         ret [4 + slen * sizeof(gunichar2)] = 0;
109         ret [5 + slen * sizeof(gunichar2)] = 0;
110
111         return (gunichar2*)(ret + 4);
112 #endif
113 }
114
115 #define marshal_new0(type,size)       ((type *) marshal_alloc0 (sizeof (type)* (size)))
116
117 LIBTEST_API int STDCALL
118 mono_cominterop_is_supported (void)
119 {
120 #if defined(TARGET_X86) || defined(TARGET_AMD64)
121         return 1;
122 #endif
123         return 0;
124 }
125
126 LIBTEST_API unsigned short* STDCALL
127 test_lpwstr_marshal (unsigned short* chars, long length)
128 {
129         int i = 0;
130         unsigned short *res;
131
132         res = marshal_alloc (2 * (length + 1));
133
134         // printf("test_lpwstr_marshal()\n");
135         
136         while ( i < length ) {
137                 // printf("X|%u|\n", chars[i]);
138                 res [i] = chars[i];
139                 i++;
140         }
141
142         res [i] = 0;
143
144         return res;
145 }
146
147
148 LIBTEST_API void STDCALL
149 test_lpwstr_marshal_out (unsigned short** chars)
150 {
151         int i = 0;
152         const char abc[] = "ABC";
153         glong len = strlen(abc);
154
155         *chars = marshal_alloc (2 * (len + 1));
156         
157         while ( i < len ) {
158                 (*chars) [i] = abc[i];
159                 i++;
160         }
161
162         (*chars) [i] = 0;
163 }
164
165 typedef struct {
166         int b;
167         int a;
168         int c;
169 } union_test_1_type;
170
171 LIBTEST_API int STDCALL  
172 mono_union_test_1 (union_test_1_type u1) {
173         // printf ("Got values %d %d %d\n", u1.b, u1.a, u1.c);
174         return u1.a + u1.b + u1.c;
175 }
176
177 LIBTEST_API int STDCALL  
178 mono_return_int (int a) {
179         // printf ("Got value %d\n", a);
180         return a;
181 }
182
183 LIBTEST_API float STDCALL  
184 mono_test_marshal_pass_return_float (float f) {
185         return f + 1.0;
186 }
187
188 struct ss
189 {
190         int i;
191 };
192
193 LIBTEST_API int STDCALL 
194 mono_return_int_ss (struct ss a) {
195         // printf ("Got value %d\n", a.i);
196         return a.i;
197 }
198
199 LIBTEST_API struct ss STDCALL
200 mono_return_ss (struct ss a) {
201         // printf ("Got value %d\n", a.i);
202         a.i++;
203         return a;
204 }
205
206 struct sc1
207 {
208         char c[1];
209 };
210
211 LIBTEST_API struct sc1 STDCALL
212 mono_return_sc1 (struct sc1 a) {
213         // printf ("Got value %d\n", a.c[0]);
214         a.c[0]++;
215         return a;
216 }
217
218
219 struct sc3
220 {
221         char c[3];
222 };
223
224 LIBTEST_API struct sc3 STDCALL 
225 mono_return_sc3 (struct sc3 a) {
226         // printf ("Got values %d %d %d\n", a.c[0], a.c[1], a.c[2]);
227         a.c[0]++;
228         a.c[1] += 2;
229         a.c[2] += 3;
230         return a;
231 }
232
233 struct sc5
234 {
235         char c[5];
236 };
237
238 LIBTEST_API struct sc5 STDCALL 
239 mono_return_sc5 (struct sc5 a) {
240         // printf ("Got values %d %d %d %d %d\n", a.c[0], a.c[1], a.c[2], a.c[3], a.c[4]);
241         a.c[0]++;
242         a.c[1] += 2;
243         a.c[2] += 3;
244         a.c[3] += 4;
245         a.c[4] += 5;
246         return a;
247 }
248
249 union su
250 {
251         int i1;
252         int i2;
253 };
254
255 LIBTEST_API int STDCALL  
256 mono_return_int_su (union su a) {
257         // printf ("Got value %d\n", a.i1);
258         return a.i1;
259 }
260
261 struct FI {
262         float f1;
263         float f2;
264         float f3;
265 };
266
267 struct NestedFloat {
268         struct FI fi;
269         float f4;
270 };
271
272 LIBTEST_API struct NestedFloat STDCALL
273 mono_return_nested_float (void)
274 {
275         struct NestedFloat f;
276         f.fi.f1 = 1.0;
277         f.fi.f2 = 2.0;
278         f.fi.f3 = 3.0;
279         f.f4 = 4.0;
280         return f;
281 }
282
283 LIBTEST_API int STDCALL  
284 mono_test_many_int_arguments (int a, int b, int c, int d, int e,
285                                                           int f, int g, int h, int i, int j);
286 LIBTEST_API short STDCALL 
287 mono_test_many_short_arguments (short a, short b, short c, short d, short e,
288                                                                 short f, short g, short h, short i, short j);
289 LIBTEST_API char STDCALL 
290 mono_test_many_char_arguments (char a, char b, char c, char d, char e,
291                                                            char f, char g, char h, char i, char j);
292
293 LIBTEST_API int STDCALL 
294 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)
295 {
296         return a + b + c + d + e + f + g + h + i + j;
297 }
298
299 LIBTEST_API short STDCALL 
300 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)
301 {
302         return a + b + c + d + e + f + g + h + i + j;
303 }
304
305 LIBTEST_API char STDCALL 
306 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)
307 {
308         return a + b + c + d + e + f + g + h + i + j;
309 }
310
311 LIBTEST_API float STDCALL 
312 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)
313 {
314         return a + b + c + d + e + f + g + h + i + j;
315 }
316
317 LIBTEST_API double STDCALL 
318 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)
319 {
320         return a + b + c + d + e + f + g + h + i + j;
321 }
322
323 LIBTEST_API double STDCALL 
324 mono_test_split_double_arguments (double a, double b, float c, double d, double e)
325 {
326         return a + b + c + d + e;
327 }
328
329 LIBTEST_API int STDCALL 
330 mono_test_puts_static (char *s)
331 {
332         // printf ("TEST %s\n", s);
333         return 1;
334 }
335
336 typedef int (STDCALL *SimpleDelegate3) (int a, int b);
337
338 LIBTEST_API int STDCALL 
339 mono_invoke_delegate (SimpleDelegate3 delegate)
340 {
341         int res;
342
343         // printf ("start invoke %p\n", delegate);
344
345         res = delegate (2, 3);
346
347         // printf ("end invoke\n");
348
349         return res;
350 }
351
352 LIBTEST_API int STDCALL
353 mono_invoke_simple_delegate (SimpleDelegate d)
354 {
355         return d (4);
356 }
357
358 LIBTEST_API int STDCALL  
359 mono_test_marshal_char (short a1)
360 {
361         if (a1 == 'a')
362                 return 0;
363         
364         return 1;
365 }
366
367 LIBTEST_API void STDCALL
368 mono_test_marshal_char_array (gunichar2 *s)
369 {
370         const char m[] = "abcdef";
371         gunichar2* s2;
372         glong len;
373
374         s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
375         
376         len = (len * 2) + 2;
377         memcpy (s, s2, len);
378
379         g_free (s2);
380 }
381
382 LIBTEST_API int STDCALL
383 mono_test_marshal_ansi_char_array (char *s)
384 {
385         const char m[] = "abcdef";
386
387         if (strncmp ("qwer", s, 4))
388                 return 1;
389
390         memcpy (s, m, sizeof (m));
391         return 0;
392 }
393
394 LIBTEST_API int STDCALL
395 mono_test_marshal_unicode_char_array (gunichar2 *s)
396 {
397         const char m[] = "abcdef";
398         const char expected[] = "qwer";
399         gunichar2 *s1, *s2;
400         glong len1, len2;
401
402         s1 = g_utf8_to_utf16 (m, -1, NULL, &len1, NULL);
403         s2 = g_utf8_to_utf16 (expected, -1, NULL, &len2, NULL);
404         len1 = (len1 * 2);
405         len2 = (len2 * 2);
406
407         if (memcmp (s, s2, len2))
408                 return 1;
409
410         memcpy (s, s1, len1);
411         return 0;
412 }
413
414 LIBTEST_API int STDCALL 
415 mono_test_empty_pinvoke (int i)
416 {
417         return i;
418 }
419
420 LIBTEST_API int STDCALL  
421 mono_test_marshal_bool_byref (int a, int *b, int c)
422 {
423     int res = *b;
424
425         *b = 1;
426
427         return res;
428 }
429
430 LIBTEST_API int STDCALL 
431 mono_test_marshal_bool_in_as_I1_U1 (char bTrue, char bFalse)
432 {
433         if (!bTrue)
434                 return 1;
435         if (bFalse)
436                 return 2;
437         return 0;
438 }
439
440 LIBTEST_API int STDCALL 
441 mono_test_marshal_bool_out_as_I1_U1 (char* bTrue, char* bFalse)
442 {
443         if (!bTrue || !bFalse)
444                 return 3;
445
446         *bTrue = 1;
447         *bFalse = 0;
448
449         return 0;
450 }
451
452 LIBTEST_API int STDCALL 
453 mono_test_marshal_bool_ref_as_I1_U1 (char* bTrue, char* bFalse)
454 {
455         if (!bTrue || !bFalse)
456                 return 4;
457
458         if (!(*bTrue))
459                 return 5;
460         if (*bFalse)
461                 return 6;
462
463         *bFalse = 1;
464         *bTrue = 0;
465
466         return 0;
467 }
468
469 LIBTEST_API int STDCALL  
470 mono_test_marshal_array (int *a1)
471 {
472         int i, sum = 0;
473
474         for (i = 0; i < 50; i++)
475                 sum += a1 [i];
476         
477         return sum;
478 }
479
480 LIBTEST_API int STDCALL  
481 mono_test_marshal_inout_array (int *a1)
482 {
483         int i, sum = 0;
484
485         for (i = 0; i < 50; i++) {
486                 sum += a1 [i];
487                 a1 [i] = 50 - a1 [i];
488         }
489         
490         return sum;
491 }
492
493 LIBTEST_API int /* cdecl */
494 mono_test_marshal_inout_array_cdecl (int *a1)
495 {
496         return mono_test_marshal_inout_array (a1);
497 }
498
499 LIBTEST_API int STDCALL  
500 mono_test_marshal_out_array (int *a1)
501 {
502         int i;
503
504         for (i = 0; i < 50; i++) {
505                 a1 [i] = i;
506         }
507         
508         return 0;
509 }
510
511 LIBTEST_API int STDCALL
512 mono_test_marshal_out_byref_array_out_size_param (int **out_arr, int *out_len)
513 {
514         int *arr;
515         int i, len;
516
517         len = 4;
518         arr = marshal_alloc (sizeof (gint32) * len);
519         for (i = 0; i < len; ++i)
520                 arr [i] = i;
521         *out_arr = arr;
522         *out_len = len;
523
524         return 0;
525 }
526
527 LIBTEST_API int STDCALL  
528 mono_test_marshal_inout_nonblittable_array (gunichar2 *a1)
529 {
530         int i, sum = 0;
531
532         for (i = 0; i < 10; i++) {
533                 a1 [i] = 'F';
534         }
535         
536         return sum;
537 }
538
539 typedef struct {
540         int a;
541         int b;
542         int c;
543         const char *d;
544         gunichar2 *d2;
545 } simplestruct;
546
547 typedef struct {
548         double x;
549         double y;
550 } point;
551
552 LIBTEST_API simplestruct STDCALL 
553 mono_test_return_vtype (int i)
554 {
555         simplestruct res;
556         static gunichar2 test2 [] = { 'T', 'E', 'S', 'T', '2', 0 };
557
558         res.a = 0;
559         res.b = 1;
560         res.c = 0;
561         res.d = "TEST";
562         res.d2 = test2;
563
564         return res;
565 }
566
567 LIBTEST_API void STDCALL
568 mono_test_delegate_struct (void)
569 {
570         // printf ("TEST\n");
571 }
572
573 typedef char* (STDCALL *ReturnStringDelegate) (const char *s);
574
575 LIBTEST_API char * STDCALL 
576 mono_test_return_string (ReturnStringDelegate func)
577 {
578         char *res;
579
580         // printf ("mono_test_return_string\n");
581
582         res = func ("TEST");
583         marshal_free (res);
584
585         // printf ("got string: %s\n", res);
586         return marshal_strdup ("12345");
587 }
588
589 typedef int (STDCALL *RefVTypeDelegate) (int a, simplestruct *ss, int b);
590
591 LIBTEST_API int STDCALL 
592 mono_test_ref_vtype (int a, simplestruct *ss, int b, RefVTypeDelegate func)
593 {
594         if (a == 1 && b == 2 && ss->a == 0 && ss->b == 1 && ss->c == 0 &&
595             !strcmp (ss->d, "TEST1")) {
596                 ss->a = 1;
597                 ss->b = 0;
598                 ss->c = 1;
599                 ss->d = "TEST2";
600
601                 return func (a, ss, b);
602         }
603
604         return 1;
605 }
606
607 typedef int (STDCALL *OutVTypeDelegate) (int a, simplestruct *ss, int b);
608
609 LIBTEST_API int STDCALL 
610 mono_test_marshal_out_struct (int a, simplestruct *ss, int b, OutVTypeDelegate func)
611 {
612         /* Check that the input pointer is ignored */
613         ss->d = (gpointer)0x12345678;
614
615         func (a, ss, b);
616
617         if (ss->a && ss->b && ss->c && !strcmp (ss->d, "TEST3"))
618                 return 0;
619         else
620                 return 1;
621 }
622
623 typedef int (STDCALL *InVTypeDelegate) (int a, simplestruct *ss, int b);
624
625 LIBTEST_API int STDCALL 
626 mono_test_marshal_in_struct (int a, simplestruct *ss, int b, InVTypeDelegate func)
627 {
628         simplestruct ss2;
629         int res;
630
631         memcpy (&ss2, ss, sizeof (simplestruct));
632
633         res = func (a, ss, b);
634         if (res) {
635                 printf ("mono_test_marshal_in_struct () failed: %d\n", res);
636                 return 1;
637         }
638
639         /* Check that no modifications is made to the struct */
640         if (ss2.a == ss->a && ss2.b == ss->b && ss2.c == ss->c && ss2.d == ss->d)
641                 return 0;
642         else
643                 return 1;
644 }
645
646 typedef struct {
647         int a;
648         SimpleDelegate func, func2, func3;
649 } DelegateStruct;
650
651 LIBTEST_API DelegateStruct STDCALL 
652 mono_test_marshal_delegate_struct (DelegateStruct ds)
653 {
654         DelegateStruct res;
655
656         res.a = ds.func (ds.a) + ds.func2 (ds.a) + (ds.func3 == NULL ? 0 : 1);
657         res.func = ds.func;
658         res.func2 = ds.func2;
659         res.func3 = NULL;
660
661         return res;
662 }
663
664 LIBTEST_API int STDCALL  
665 mono_test_marshal_struct (simplestruct ss)
666 {
667         if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
668             !strcmp (ss.d, "TEST"))
669                 return 0;
670
671         return 1;
672 }
673
674 LIBTEST_API int STDCALL 
675 mono_test_marshal_byref_struct (simplestruct *ss, int a, int b, int c, char *d)
676 {
677         gboolean res = (ss->a == a && ss->b == b && ss->c == c && strcmp (ss->d, d) == 0);
678
679         marshal_free ((char*)ss->d);
680
681         ss->a = !ss->a;
682         ss->b = !ss->b;
683         ss->c = !ss->c;
684         ss->d = marshal_strdup ("DEF");
685
686         return res ? 0 : 1;
687 }
688
689 typedef struct {
690         int a;
691         int b;
692         int c;
693         char *d;
694         unsigned char e;
695         double f;
696         unsigned char g;
697         guint64 h;
698 } simplestruct2;
699
700 LIBTEST_API int STDCALL 
701 mono_test_marshal_struct2 (simplestruct2 ss)
702 {
703         if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
704             !strcmp (ss.d, "TEST") && 
705             ss.e == 99 && ss.f == 1.5 && ss.g == 42 && ss.h == (guint64)123)
706                 return 0;
707
708         return 1;
709 }
710
711 /* on HP some of the struct should be on the stack and not in registers */
712 LIBTEST_API int STDCALL 
713 mono_test_marshal_struct2_2 (int i, int j, int k, simplestruct2 ss)
714 {
715         if (i != 10 || j != 11 || k != 12)
716                 return 1;
717         if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
718             !strcmp (ss.d, "TEST") && 
719             ss.e == 99 && ss.f == 1.5 && ss.g == 42 && ss.h == (guint64)123)
720                 return 0;
721
722         return 1;
723 }
724
725 LIBTEST_API int STDCALL  
726 mono_test_marshal_lpstruct (simplestruct *ss)
727 {
728         if (ss->a == 0 && ss->b == 1 && ss->c == 0 &&
729             !strcmp (ss->d, "TEST"))
730                 return 0;
731
732         return 1;
733 }
734
735 LIBTEST_API int STDCALL  
736 mono_test_marshal_lpstruct_blittable (point *p)
737 {
738         if (p->x == 1.0 && p->y == 2.0)
739                 return 0;
740         else
741                 return 1;
742 }
743
744 LIBTEST_API int STDCALL 
745 mono_test_marshal_struct_array (simplestruct2 *ss)
746 {
747         if (! (ss[0].a == 0 && ss[0].b == 1 && ss[0].c == 0 &&
748                    !strcmp (ss[0].d, "TEST") && 
749                    ss[0].e == 99 && ss[0].f == 1.5 && ss[0].g == 42 && ss[0].h == (guint64)123))
750                 return 1;
751
752         if (! (ss[1].a == 0 && ss[1].b == 0 && ss[1].c == 0 &&
753                    !strcmp (ss[1].d, "TEST2") && 
754                    ss[1].e == 100 && ss[1].f == 2.5 && ss[1].g == 43 && ss[1].h == (guint64)124))
755                 return 1;
756
757         return 0;
758 }
759
760 typedef struct long_align_struct {
761         gint32 a;
762         gint64 b;
763         gint64 c;
764 } long_align_struct;
765
766 LIBTEST_API int STDCALL 
767 mono_test_marshal_long_align_struct_array (long_align_struct *ss)
768 {
769         return ss[0].a + ss[0].b + ss[0].c + ss[1].a + ss[1].b + ss[1].c;
770 }
771
772 LIBTEST_API simplestruct2 * STDCALL 
773 mono_test_marshal_class (int i, int j, int k, simplestruct2 *ss, int l)
774 {
775         simplestruct2 *res;
776
777         if (!ss)
778                 return NULL;
779
780         if (i != 10 || j != 11 || k != 12 || l != 14)
781                 return NULL;
782         if (! (ss->a == 0 && ss->b == 1 && ss->c == 0 &&
783                    !strcmp (ss->d, "TEST") && 
784                    ss->e == 99 && ss->f == 1.5 && ss->g == 42 && ss->h == (guint64)123))
785                 return NULL;
786
787         res = marshal_new0 (simplestruct2, 1);
788         memcpy (res, ss, sizeof (simplestruct2));
789         res->d = marshal_strdup ("TEST");
790         return res;
791 }
792
793 LIBTEST_API int STDCALL 
794 mono_test_marshal_byref_class (simplestruct2 **ssp)
795 {
796         simplestruct2 *ss = *ssp;
797         simplestruct2 *res;
798         
799         if (! (ss->a == 0 && ss->b == 1 && ss->c == 0 &&
800                    !strcmp (ss->d, "TEST") && 
801                    ss->e == 99 && ss->f == 1.5 && ss->g == 42 && ss->h == (guint64)123))
802                 return 1;
803
804         res = marshal_new0 (simplestruct2, 1);
805         memcpy (res, ss, sizeof (simplestruct2));
806         res->d = marshal_strdup ("TEST-RES");
807
808         *ssp = res;
809         return 0;
810 }
811
812 static void *
813 get_sp (void)
814 {
815         int i;
816         void *p;
817
818         /* Yes, this is correct, we are only trying to determine the value of the stack here */
819         p = &i;
820         return p;
821 }
822
823 LIBTEST_API int STDCALL 
824 reliable_delegate (int a)
825 {
826         return a;
827 }
828
829 /*
830  * Checks whether get_sp() works as expected. It doesn't work with gcc-2.95.3 on linux.
831  */
832 static gboolean
833 is_get_sp_reliable (void)
834 {
835         void *sp1, *sp2;
836
837         reliable_delegate(1);
838         sp1 = get_sp();
839         reliable_delegate(1);
840         sp2 = get_sp();
841         return sp1 == sp2;
842
843
844 LIBTEST_API int STDCALL 
845 mono_test_marshal_delegate (SimpleDelegate delegate)
846 {
847         void *sp1, *sp2;
848
849         /* Check that the delegate wrapper is stdcall */
850         delegate (2);
851         sp1 = get_sp ();
852         delegate (2);
853         sp2 = get_sp ();
854         if (is_get_sp_reliable())
855                 g_assert (sp1 == sp2);
856
857         return delegate (2);
858 }
859
860 static int STDCALL inc_cb (int i)
861 {
862         return i + 1;
863 }
864
865 LIBTEST_API int STDCALL 
866 mono_test_marshal_out_delegate (SimpleDelegate *delegate)
867 {
868         *delegate = inc_cb;
869
870         return 0;
871 }
872
873 LIBTEST_API SimpleDelegate STDCALL 
874 mono_test_marshal_return_delegate (SimpleDelegate delegate)
875 {
876         return delegate;
877 }
878
879 static int STDCALL
880 return_plus_one (int i)
881 {
882         return i + 1;
883 }
884
885 LIBTEST_API SimpleDelegate STDCALL 
886 mono_test_marshal_return_delegate_2 (void)
887 {
888         return return_plus_one;
889 }
890
891 typedef simplestruct (STDCALL *SimpleDelegate2) (simplestruct ss);
892
893 static gboolean
894 is_utf16_equals (gunichar2 *s1, const char *s2)
895 {
896         char *s;
897         int res;
898
899         s = g_utf16_to_utf8 (s1, -1, NULL, NULL, NULL);
900         res = strcmp (s, s2);
901         g_free (s);
902
903         return res == 0;
904 }
905
906 LIBTEST_API int STDCALL 
907 mono_test_marshal_delegate2 (SimpleDelegate2 delegate)
908 {
909         simplestruct ss, res;
910
911         ss.a = 0;
912         ss.b = 1;
913         ss.c = 0;
914         ss.d = "TEST";
915         ss.d2 = g_utf8_to_utf16 ("TEST2", -1, NULL, NULL, NULL); 
916
917         res = delegate (ss);
918         if (! (res.a && !res.b && res.c && !strcmp (res.d, "TEST-RES") && is_utf16_equals (res.d2, "TEST2-RES")))
919                 return 1;
920
921         return 0;
922 }
923
924 typedef simplestruct* (STDCALL *SimpleDelegate4) (simplestruct *ss);
925
926 LIBTEST_API int STDCALL 
927 mono_test_marshal_delegate4 (SimpleDelegate4 delegate)
928 {
929         simplestruct ss;
930         simplestruct *res;
931
932         ss.a = 0;
933         ss.b = 1;
934         ss.c = 0;
935         ss.d = "TEST";
936
937         /* Check argument */
938         res = delegate (&ss);
939         if (!res)
940                 return 1;
941
942         /* Check return value */
943         if (! (!res->a && res->b && !res->c && !strcmp (res->d, "TEST")))
944                 return 2;
945
946         /* Check NULL argument and NULL result */
947         res = delegate (NULL);
948         if (res)
949                 return 3;
950
951         return 0;
952 }
953
954 typedef int (STDCALL *SimpleDelegate5) (simplestruct **ss);
955
956 LIBTEST_API int STDCALL 
957 mono_test_marshal_delegate5 (SimpleDelegate5 delegate)
958 {
959         simplestruct ss;
960         int res;
961         simplestruct *ptr;
962
963         ss.a = 0;
964         ss.b = 1;
965         ss.c = 0;
966         ss.d = "TEST";
967
968         ptr = &ss;
969
970         res = delegate (&ptr);
971         if (res != 0)
972                 return 1;
973
974         if (!(ptr->a && !ptr->b && ptr->c && !strcmp (ptr->d, "RES")))
975                 return 2;
976
977         return 0;
978 }
979
980 LIBTEST_API int STDCALL 
981 mono_test_marshal_delegate6 (SimpleDelegate5 delegate)
982 {
983         int res;
984
985         res = delegate (NULL);
986
987         return 0;
988 }
989
990 typedef int (STDCALL *SimpleDelegate7) (simplestruct **ss);
991
992 LIBTEST_API int STDCALL 
993 mono_test_marshal_delegate7 (SimpleDelegate7 delegate)
994 {
995         int res;
996         simplestruct *ptr;
997
998         /* Check that the input pointer is ignored */
999         ptr = (gpointer)0x12345678;
1000
1001         res = delegate (&ptr);
1002         if (res != 0)
1003                 return 1;
1004
1005         if (!(ptr->a && !ptr->b && ptr->c && !strcmp (ptr->d, "RES")))
1006                 return 2;
1007
1008         return 0;
1009 }
1010
1011 typedef int (STDCALL *InOutByvalClassDelegate) (simplestruct *ss);
1012
1013 LIBTEST_API int STDCALL 
1014 mono_test_marshal_inout_byval_class_delegate (InOutByvalClassDelegate delegate)
1015 {
1016         int res;
1017         simplestruct ss;
1018
1019         ss.a = FALSE;
1020         ss.b = TRUE;
1021         ss.c = FALSE;
1022         ss.d = g_strdup_printf ("%s", "FOO");
1023
1024         res = delegate (&ss);
1025         if (res != 0)
1026                 return 1;
1027
1028         if (!(ss.a && !ss.b && ss.c && !strcmp (ss.d, "RES")))
1029                 return 2;
1030
1031         return 0;
1032 }
1033
1034 typedef int (STDCALL *SimpleDelegate8) (gunichar2 *s);
1035
1036 LIBTEST_API int STDCALL 
1037 mono_test_marshal_delegate8 (SimpleDelegate8 delegate, gunichar2 *s)
1038 {
1039         return delegate (s);
1040 }
1041
1042 typedef int (STDCALL *return_int_fnt) (int i);
1043 typedef int (STDCALL *SimpleDelegate9) (return_int_fnt d);
1044
1045 LIBTEST_API int STDCALL 
1046 mono_test_marshal_delegate9 (SimpleDelegate9 delegate, gpointer ftn)
1047 {
1048         return delegate (ftn);
1049 }
1050
1051 static int STDCALL 
1052 return_self (int i)
1053 {
1054         return i;
1055 }
1056
1057 LIBTEST_API int STDCALL 
1058 mono_test_marshal_delegate10 (SimpleDelegate9 delegate)
1059 {
1060         return delegate (return_self);
1061 }
1062
1063 typedef int (STDCALL *PrimitiveByrefDelegate) (int *i);
1064
1065 LIBTEST_API int STDCALL 
1066 mono_test_marshal_primitive_byref_delegate (PrimitiveByrefDelegate delegate)
1067 {
1068         int i = 1;
1069
1070         int res = delegate (&i);
1071         if (res != 0)
1072                 return res;
1073
1074         if (i != 2)
1075                 return 2;
1076
1077         return 0;
1078 }
1079
1080 typedef int (STDCALL *return_int_delegate) (int i);
1081
1082 typedef return_int_delegate (STDCALL *ReturnDelegateDelegate) (void);
1083
1084 LIBTEST_API int STDCALL 
1085 mono_test_marshal_return_delegate_delegate (ReturnDelegateDelegate d)
1086 {
1087         return (d ()) (55);
1088 }
1089
1090 LIBTEST_API int STDCALL  
1091 mono_test_marshal_stringbuilder (char *s, int n)
1092 {
1093         const char m[] = "This is my message.  Isn't it nice?";
1094
1095         if (strcmp (s, "ABCD") != 0)
1096                 return 1;
1097         strncpy(s, m, n);
1098         s [n] = '\0';
1099         return 0;
1100 }
1101
1102 LIBTEST_API int STDCALL  
1103 mono_test_marshal_stringbuilder2 (char *s, int n)
1104 {
1105         const char m[] = "EFGH";
1106
1107         strncpy(s, m, n);
1108         s [n] = '\0';
1109         return 0;
1110 }
1111
1112 LIBTEST_API int STDCALL  
1113 mono_test_marshal_stringbuilder_default (char *s, int n)
1114 {
1115         const char m[] = "This is my message.  Isn't it nice?";
1116
1117         strncpy(s, m, n);
1118         s [n] = '\0';
1119         return 0;
1120 }
1121
1122 LIBTEST_API int STDCALL  
1123 mono_test_marshal_stringbuilder_unicode (gunichar2 *s, int n)
1124 {
1125         const char m[] = "This is my message.  Isn't it nice?";
1126         gunichar2* s2;
1127         glong len;
1128
1129         s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
1130         
1131         len = (len * 2) + 2;
1132         if (len > (n * 2))
1133                 len = n * 2;
1134         memcpy (s, s2, len);
1135
1136         g_free (s2);
1137
1138         return 0;
1139 }
1140
1141 LIBTEST_API void STDCALL
1142 mono_test_marshal_stringbuilder_out (char **s)
1143 {
1144         const char m[] = "This is my message.  Isn't it nice?";
1145         char *str;
1146
1147         str = marshal_alloc (strlen (m) + 1);
1148         memcpy (str, m, strlen (m) + 1);
1149         
1150         *s = str;
1151 }
1152
1153 LIBTEST_API int STDCALL  
1154 mono_test_marshal_stringbuilder_out_unicode (gunichar2 **s)
1155 {
1156         const char m[] = "This is my message.  Isn't it nice?";
1157         gunichar2 *s2;
1158         glong len;
1159
1160         s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
1161         
1162         len = (len * 2) + 2;
1163         *s = marshal_alloc (len);
1164         memcpy (*s, s2, len);
1165
1166         g_free (s2);
1167
1168         return 0;
1169 }
1170
1171 LIBTEST_API int STDCALL
1172 mono_test_marshal_stringbuilder_ref (char **s)
1173 {
1174         const char m[] = "This is my message.  Isn't it nice?";
1175         char *str;
1176
1177         if (strcmp (*s, "ABC"))
1178                 return 1;
1179
1180         str = marshal_alloc (strlen (m) + 1);
1181         memcpy (str, m, strlen (m) + 1);
1182         
1183         *s = str;
1184         return 0;
1185 }
1186
1187 typedef struct {
1188 #ifndef __GNUC__
1189     char a;
1190 #endif
1191 } EmptyStruct;
1192
1193 LIBTEST_API int STDCALL 
1194 mono_test_marshal_empty_string_array (char **array)
1195 {
1196         return (array == NULL) ? 0 : 1;
1197 }
1198
1199 LIBTEST_API int STDCALL 
1200 mono_test_marshal_string_array (char **array)
1201 {
1202         if (strcmp (array [0], "ABC"))
1203                 return 1;
1204         if (strcmp (array [1], "DEF"))
1205                 return 2;
1206
1207         if (array [2] != NULL)
1208                 return 3;
1209
1210         return 0;
1211 }
1212
1213 LIBTEST_API int STDCALL 
1214 mono_test_marshal_byref_string_array (char ***array)
1215 {
1216         if (*array == NULL)
1217                 return 0;
1218
1219         if (strcmp ((*array) [0], "Alpha"))
1220                 return 2;
1221         if (strcmp ((*array) [1], "Beta"))
1222                 return 2;
1223         if (strcmp ((*array) [2], "Gamma"))
1224                 return 2;
1225
1226         return 1;
1227 }
1228
1229 LIBTEST_API int STDCALL 
1230 mono_test_marshal_stringbuilder_array (char **array)
1231 {
1232         if (strcmp (array [0], "ABC"))
1233                 return 1;
1234         if (strcmp (array [1], "DEF"))
1235                 return 2;
1236
1237         strcpy (array [0], "DEF");
1238         strcpy (array [1], "ABC");
1239
1240         return 0;
1241 }
1242
1243 LIBTEST_API int STDCALL 
1244 mono_test_marshal_unicode_string_array (gunichar2 **array, char **array2)
1245 {
1246         GError *error = NULL;
1247         char *s;
1248         
1249         s = g_utf16_to_utf8 (array [0], -1, NULL, NULL, &error);
1250         if (strcmp (s, "ABC")) {
1251                 g_free (s);
1252                 return 1;
1253         }
1254         else
1255                 g_free (s);
1256
1257         s = g_utf16_to_utf8 (array [1], -1, NULL, NULL, &error);
1258         if (strcmp (s, "DEF")) {
1259                 g_free (s);
1260                 return 2;
1261         }
1262         else
1263                 g_free (s);
1264
1265         if (strcmp (array2 [0], "ABC"))
1266                 return 3;
1267
1268         if (strcmp (array2 [1], "DEF")) 
1269                 return 4;
1270
1271         return 0;
1272 }
1273
1274 /* this does not work on Redhat gcc 2.96 */
1275 LIBTEST_API int STDCALL  
1276 mono_test_empty_struct (int a, EmptyStruct es, int b)
1277 {
1278         // printf ("mono_test_empty_struct %d %d\n", a, b);
1279
1280         // Intel icc on ia64 passes 'es' in 2 registers
1281 #if defined(__ia64) && defined(__INTEL_COMPILER)
1282         return 0;
1283 #else
1284         if (a == 1 && b == 2)
1285                 return 0;
1286         return 1;
1287 #endif
1288 }
1289
1290 typedef struct {
1291        char a[100];
1292 } ByValStrStruct;
1293
1294 LIBTEST_API ByValStrStruct * STDCALL 
1295 mono_test_byvalstr_gen (void)
1296 {
1297         ByValStrStruct *ret;
1298        
1299         ret = malloc(sizeof(ByValStrStruct));
1300         memset(ret, 'a', sizeof(ByValStrStruct)-1);
1301         ret->a[sizeof(ByValStrStruct)-1] = 0;
1302
1303         return ret;
1304 }
1305
1306 LIBTEST_API int STDCALL 
1307 mono_test_byvalstr_check (ByValStrStruct* data, char* correctString)
1308 {
1309         int ret;
1310
1311         ret = strcmp(data->a, correctString);
1312         // printf ("T1: %s\n", data->a);
1313         // printf ("T2: %s\n", correctString);
1314
1315         /* we need g_free because the allocation was performed by mono_test_byvalstr_gen */
1316         g_free (data);
1317         return (ret != 0);
1318 }
1319
1320 typedef struct {
1321         guint16 a[4];
1322         int  flag;
1323 } ByValStrStruct_Unicode;
1324
1325 LIBTEST_API int STDCALL 
1326 mono_test_byvalstr_check_unicode (ByValStrStruct_Unicode *ref, int test)
1327 {
1328         if (ref->flag != 0x1234abcd){
1329                 printf ("overwritten data");
1330                 return 1;
1331         }
1332             
1333         if (test == 1 || test == 3){
1334                 if (ref->a [0] != '1' ||
1335                     ref->a [1] != '2'   ||
1336                     ref->a [2] != '3')
1337                         return 1;
1338                 return 0;
1339         }
1340         if (test == 2){
1341                 if (ref->a [0] != '1' ||
1342                     ref->a [1] != '2')
1343                         return 1;
1344                 return 0;
1345         }
1346         return 10;
1347 }
1348
1349 LIBTEST_API int STDCALL 
1350 NameManglingAnsi (char *data)
1351 {
1352         return data [0] + data [1] + data [2];
1353 }
1354
1355 LIBTEST_API int STDCALL 
1356 NameManglingAnsiA (char *data)
1357 {
1358         g_assert_not_reached ();
1359 }
1360
1361 LIBTEST_API int STDCALL 
1362 NameManglingAnsiW (char *data)
1363 {
1364         g_assert_not_reached ();
1365 }
1366
1367 LIBTEST_API int STDCALL 
1368 NameManglingAnsi2A (char *data)
1369 {
1370         return data [0] + data [1] + data [2];
1371 }
1372
1373 LIBTEST_API int STDCALL 
1374 NameManglingAnsi2W (char *data)
1375 {
1376         g_assert_not_reached ();
1377 }
1378
1379 LIBTEST_API int STDCALL 
1380 NameManglingUnicode (char *data)
1381 {
1382         g_assert_not_reached ();
1383 }
1384
1385 LIBTEST_API int STDCALL 
1386 NameManglingUnicodeW (gunichar2 *data)
1387 {
1388         return data [0] + data [1] + data [2];
1389 }
1390
1391 LIBTEST_API int STDCALL 
1392 NameManglingUnicode2 (gunichar2 *data)
1393 {
1394         return data [0] + data [1] + data [2];
1395 }
1396
1397 LIBTEST_API int STDCALL 
1398 NameManglingAutoW (char *data)
1399 {
1400 #ifdef WIN32
1401         return (data [0] + data [1] + data [2]) == 131 ? 0 : 1;
1402 #else
1403         g_assert_not_reached ();
1404 #endif
1405 }
1406
1407 LIBTEST_API int STDCALL 
1408 NameManglingAuto (char *data)
1409 {
1410 #ifndef WIN32
1411         return (data [0] + data [1] + data [2]) == 198 ? 0 : 1;
1412 #else
1413         g_assert_not_reached ();
1414 #endif
1415 }
1416
1417 typedef int (STDCALL *intcharFunc)(const char*);
1418
1419 LIBTEST_API void STDCALL 
1420 callFunction (intcharFunc f)
1421 {
1422         f ("ABC");
1423 }
1424
1425 typedef struct {
1426         const char* str;
1427         int i;
1428 } SimpleObj;
1429
1430 LIBTEST_API int STDCALL 
1431 class_marshal_test0 (SimpleObj *obj1)
1432 {
1433         // printf ("class_marshal_test0 %s %d\n", obj1->str, obj1->i);
1434
1435         if (strcmp(obj1->str, "T1"))
1436                 return -1;
1437         if (obj1->i != 4)
1438                 return -2;
1439
1440         return 0;
1441 }
1442
1443 LIBTEST_API int STDCALL 
1444 class_marshal_test4 (SimpleObj *obj1)
1445 {
1446         if (obj1)
1447                 return -1;
1448
1449         return 0;
1450 }
1451
1452 LIBTEST_API void STDCALL
1453 class_marshal_test1 (SimpleObj **obj1)
1454 {
1455         SimpleObj *res = malloc (sizeof (SimpleObj));
1456
1457         res->str = marshal_strdup ("ABC");
1458         res->i = 5;
1459
1460         *obj1 = res;
1461 }
1462
1463 LIBTEST_API int STDCALL 
1464 class_marshal_test2 (SimpleObj **obj1)
1465 {
1466         // printf ("class_marshal_test2 %s %d\n", (*obj1)->str, (*obj1)->i);
1467
1468         if (strcmp((*obj1)->str, "ABC"))
1469                 return -1;
1470         if ((*obj1)->i != 5)
1471                 return -2;
1472
1473         return 0;
1474 }
1475
1476 LIBTEST_API int STDCALL 
1477 string_marshal_test0 (char *str)
1478 {
1479         if (strcmp (str, "TEST0"))
1480                 return -1;
1481
1482         return 0;
1483 }
1484
1485 LIBTEST_API void STDCALL
1486 string_marshal_test1 (const char **str)
1487 {
1488         *str = marshal_strdup ("TEST1");
1489 }
1490
1491 LIBTEST_API int STDCALL 
1492 string_marshal_test2 (char **str)
1493 {
1494         // printf ("string_marshal_test2 %s\n", *str);
1495
1496         if (strcmp (*str, "TEST1"))
1497                 return -1;
1498
1499         *str = marshal_strdup ("TEST2");
1500
1501         return 0;
1502 }
1503
1504 LIBTEST_API int STDCALL 
1505 string_marshal_test3 (char *str)
1506 {
1507         if (str)
1508                 return -1;
1509
1510         return 0;
1511 }
1512
1513 typedef struct {
1514         int a;
1515         int b;
1516 } BlittableClass;
1517
1518 LIBTEST_API BlittableClass* STDCALL 
1519 TestBlittableClass (BlittableClass *vl)
1520 {
1521         BlittableClass *res;
1522
1523         // printf ("TestBlittableClass %d %d\n", vl->a, vl->b);
1524
1525         if (vl) {
1526                 vl->a++;
1527                 vl->b++;
1528
1529                 res = marshal_new0 (BlittableClass, 1);
1530                 memcpy (res, vl, sizeof (BlittableClass));
1531         } else {
1532                 res = marshal_new0 (BlittableClass, 1);
1533                 res->a = 42;
1534                 res->b = 43;
1535         }
1536
1537         return res;
1538 }
1539
1540 typedef struct OSVERSIONINFO_STRUCT
1541
1542         int a; 
1543         int b; 
1544 } OSVERSIONINFO_STRUCT;
1545
1546 LIBTEST_API int STDCALL  
1547 MyGetVersionEx (OSVERSIONINFO_STRUCT *osvi)
1548 {
1549
1550         // printf ("GOT %d %d\n", osvi->a, osvi->b);
1551
1552         osvi->a += 1;
1553         osvi->b += 1;
1554
1555         return osvi->a + osvi->b;
1556 }
1557
1558 LIBTEST_API int STDCALL  
1559 BugGetVersionEx (int a, int b, int c, int d, int e, int f, int g, int h, OSVERSIONINFO_STRUCT *osvi)
1560 {
1561
1562         // printf ("GOT %d %d\n", osvi->a, osvi->b);
1563
1564         osvi->a += 1;
1565         osvi->b += 1;
1566
1567         return osvi->a + osvi->b;
1568 }
1569
1570 LIBTEST_API int STDCALL 
1571 mono_test_marshal_point (point pt)
1572 {
1573         // printf("point %g %g\n", pt.x, pt.y);
1574         if (pt.x == 1.25 && pt.y == 3.5)
1575                 return 0;
1576
1577         return 1;
1578 }
1579
1580 typedef struct {
1581         int x;
1582         double y;
1583 } mixed_point;
1584
1585 LIBTEST_API int STDCALL 
1586 mono_test_marshal_mixed_point (mixed_point pt)
1587 {
1588         // printf("mixed point %d %g\n", pt.x, pt.y);
1589         if (pt.x == 5 && pt.y == 6.75)
1590                 return 0;
1591
1592         return 1;
1593 }
1594
1595 LIBTEST_API int STDCALL 
1596 mono_test_marshal_mixed_point_2 (mixed_point *pt)
1597 {
1598         if (pt->x != 5 || pt->y != 6.75)
1599                 return 1;
1600
1601         pt->x = 10;
1602         pt->y = 12.35;
1603
1604         return 0;
1605 }
1606
1607 LIBTEST_API int STDCALL  
1608 marshal_test_ref_bool(int i, char *b1, short *b2, int *b3)
1609 {
1610     int res = 1;
1611     if (*b1 != 0 && *b1 != 1)
1612         return 1;
1613     if (*b2 != 0 && *b2 != -1) /* variant_bool */
1614         return 1;
1615     if (*b3 != 0 && *b3 != 1)
1616         return 1;
1617     if (i == ((*b1 << 2) | (-*b2 << 1) | *b3))
1618         res = 0;
1619     *b1 = !*b1;
1620     *b2 = ~*b2;
1621     *b3 = !*b3;
1622     return res;
1623 }
1624
1625 struct BoolStruct
1626 {
1627     int i;
1628     char b1;
1629     short b2; /* variant_bool */
1630     int b3;
1631 };
1632
1633 LIBTEST_API int STDCALL  
1634 marshal_test_bool_struct(struct BoolStruct *s)
1635 {
1636     int res = 1;
1637     if (s->b1 != 0 && s->b1 != 1)
1638         return 1;
1639     if (s->b2 != 0 && s->b2 != -1)
1640         return 1;
1641     if (s->b3 != 0 && s->b3 != 1)
1642         return 1;
1643     if (s->i == ((s->b1 << 2) | (-s->b2 << 1) | s->b3))
1644         res = 0;
1645     s->b1 = !s->b1;
1646     s->b2 = ~s->b2;
1647     s->b3 = !s->b3;
1648     return res;
1649 }
1650
1651 typedef struct {
1652         gint64 l;
1653 } LongStruct2;
1654
1655 typedef struct {
1656         int i;
1657         LongStruct2 l;
1658 } LongStruct;
1659
1660 LIBTEST_API int STDCALL
1661 mono_test_marshal_long_struct (LongStruct *s)
1662 {
1663         return s->i + s->l.l;
1664 }
1665
1666 LIBTEST_API void STDCALL
1667 mono_test_last_error (int err)
1668 {
1669 #ifdef WIN32
1670         SetLastError (err);
1671 #else
1672         errno = err;
1673 #endif
1674 }
1675
1676 LIBTEST_API int STDCALL 
1677 mono_test_asany (void *ptr, int what)
1678 {
1679         switch (what) {
1680         case 1:
1681                 return (*(int*)ptr == 5) ? 0 : 1;
1682         case 2:
1683                 return strcmp (ptr, "ABC") == 0 ? 0 : 1;
1684         case 3: {
1685                 simplestruct2 ss = *(simplestruct2*)ptr;
1686
1687                 if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
1688             !strcmp (ss.d, "TEST") && 
1689             ss.e == 99 && ss.f == 1.5 && ss.g == 42 && ss.h == (guint64)123)
1690                         return 0;
1691                 else
1692                         return 1;
1693         }
1694         case 4: {
1695                 GError *error = NULL;
1696                 char *s;
1697
1698                 s = g_utf16_to_utf8 (ptr, -1, NULL, NULL, &error);
1699
1700                 if (!s)
1701                         return 1;
1702
1703                 if (!strcmp (s, "ABC")) {
1704                         g_free (s);
1705                         return 0;
1706                 }
1707                 else {
1708                         g_free (s);
1709                         return 1;
1710                 }
1711         }
1712         default:
1713                 g_assert_not_reached ();
1714         }
1715
1716         return 1;
1717 }
1718
1719 typedef struct
1720 {
1721         int i;
1722         int j;
1723         int k;
1724         char *s;
1725 } AsAnyStruct;
1726
1727 LIBTEST_API int STDCALL 
1728 mono_test_marshal_asany_in (void* ptr)
1729 {
1730         AsAnyStruct* asAny = ptr;
1731         int res = asAny->i + asAny->j + asAny->k;
1732
1733         return res;
1734 }
1735
1736 LIBTEST_API int STDCALL 
1737 mono_test_marshal_asany_inout (void* ptr)
1738 {
1739         AsAnyStruct* asAny = ptr;
1740         int res = asAny->i + asAny->j + asAny->k;
1741
1742         marshal_free (asAny->s);
1743
1744         asAny->i = 10;
1745         asAny->j = 20;
1746         asAny->k = 30;
1747         asAny->s = 0;
1748
1749         return res;
1750 }
1751
1752 LIBTEST_API int STDCALL 
1753 mono_test_marshal_asany_out (void* ptr)
1754 {
1755         AsAnyStruct* asAny = ptr;
1756         int res = asAny->i + asAny->j + asAny->k;
1757
1758         asAny->i = 10;
1759         asAny->j = 20;
1760         asAny->k = 30;
1761         asAny->s = 0;
1762
1763         return res;
1764 }
1765
1766 /*
1767  * AMD64 marshalling tests.
1768  */
1769
1770 typedef struct amd64_struct1 {
1771         int i;
1772         int j;
1773         int k;
1774         int l;
1775 } amd64_struct1;
1776
1777 LIBTEST_API amd64_struct1 STDCALL 
1778 mono_test_marshal_amd64_pass_return_struct1 (amd64_struct1 s)
1779 {
1780         s.i ++;
1781         s.j ++;
1782         s.k ++;
1783         s.l ++;
1784
1785         return s;
1786 }
1787
1788 LIBTEST_API amd64_struct1 STDCALL 
1789 mono_test_marshal_amd64_pass_return_struct1_many_args (amd64_struct1 s, int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8)
1790 {
1791         s.i ++;
1792         s.j ++;
1793         s.k ++;
1794         s.l += 1 + i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8;
1795
1796         return s;
1797 }
1798
1799 typedef struct amd64_struct2 {
1800         int i;
1801         int j;
1802 } amd64_struct2;
1803
1804 LIBTEST_API amd64_struct2 STDCALL 
1805 mono_test_marshal_amd64_pass_return_struct2 (amd64_struct2 s)
1806 {
1807         s.i ++;
1808         s.j ++;
1809
1810         return s;
1811 }
1812
1813 typedef struct amd64_struct3 {
1814         int i;
1815 } amd64_struct3;
1816
1817 LIBTEST_API amd64_struct3 STDCALL 
1818 mono_test_marshal_amd64_pass_return_struct3 (amd64_struct3 s)
1819 {
1820         s.i ++;
1821
1822         return s;
1823 }
1824
1825 typedef struct amd64_struct4 {
1826         double d1, d2;
1827 } amd64_struct4;
1828
1829 LIBTEST_API amd64_struct4 STDCALL 
1830 mono_test_marshal_amd64_pass_return_struct4 (amd64_struct4 s)
1831 {
1832         s.d1 ++;
1833         s.d2 ++;
1834
1835         return s;
1836 }
1837
1838 /*
1839  * IA64 marshalling tests.
1840  */
1841 typedef struct test_struct5 {
1842         float d1, d2;
1843 } test_struct5;
1844
1845 LIBTEST_API test_struct5 STDCALL 
1846 mono_test_marshal_ia64_pass_return_struct5 (double d1, double d2, test_struct5 s, int i, double d3, double d4)
1847 {
1848         s.d1 += d1 + d2 + i;
1849         s.d2 += d3 + d4 + i;
1850
1851         return s;
1852 }
1853
1854 typedef struct test_struct6 {
1855         double d1, d2;
1856 } test_struct6;
1857
1858 LIBTEST_API test_struct6 STDCALL 
1859 mono_test_marshal_ia64_pass_return_struct6 (double d1, double d2, test_struct6 s, int i, double d3, double d4)
1860 {
1861         s.d1 += d1 + d2 + i;
1862         s.d2 += d3 + d4;
1863
1864         return s;
1865 }
1866
1867 static guint32 custom_res [2];
1868
1869 LIBTEST_API void* STDCALL
1870 mono_test_marshal_pass_return_custom (int i, guint32 *ptr, int j)
1871 {
1872         /* ptr will be freed by CleanupNative, so make a copy */
1873         custom_res [0] = 0; /* not allocated by AllocHGlobal */
1874         custom_res [1] = ptr [1];
1875
1876         return &custom_res;
1877 }
1878
1879 LIBTEST_API int STDCALL 
1880 mono_test_marshal_pass_out_custom (int i, guint32 **ptr, int j)
1881 {
1882         custom_res [0] = 0;
1883         custom_res [1] = i + j + 10;
1884
1885         *ptr = custom_res;
1886
1887         return 0;
1888 }
1889
1890 LIBTEST_API int STDCALL 
1891 mono_test_marshal_pass_inout_custom (int i, guint32 *ptr, int j)
1892 {
1893         ptr [0] = 0;
1894         ptr [1] = i + ptr [1] + j;
1895
1896         return 0;
1897 }
1898
1899 LIBTEST_API int STDCALL 
1900 mono_test_marshal_pass_out_byval_custom (int i, guint32 *ptr, int j)
1901 {
1902         return ptr == NULL ? 0 : 1;
1903 }
1904
1905 LIBTEST_API int STDCALL 
1906 mono_test_marshal_pass_byref_custom (int i, guint32 **ptr, int j)
1907 {
1908         (*ptr)[1] += i + j;
1909
1910         return 0;
1911 }
1912
1913 LIBTEST_API void* STDCALL
1914 mono_test_marshal_pass_return_custom2 (int i, guint32 *ptr, int j)
1915 {
1916         g_assert_not_reached ();
1917
1918         return NULL;
1919 }
1920
1921 LIBTEST_API void* STDCALL
1922 mono_test_marshal_pass_return_custom_null (int i, guint32 *ptr, int j)
1923 {
1924         g_assert (ptr == NULL);
1925
1926         return NULL;
1927 }
1928
1929 typedef void *(STDCALL *PassReturnPtrDelegate) (void *ptr);
1930
1931 LIBTEST_API int STDCALL 
1932 mono_test_marshal_pass_return_custom_in_delegate (PassReturnPtrDelegate del)
1933 {
1934         guint32 buf [2];
1935         guint32 res;
1936         guint32 *ptr;
1937
1938         buf [0] = 0;
1939         buf [1] = 10;
1940
1941         ptr = del (&buf);
1942
1943         res = ptr [1];
1944
1945 #ifdef WIN32
1946         /* FIXME: Freed with FreeHGlobal */
1947 #else
1948         g_free (ptr);
1949 #endif
1950
1951         return res;
1952 }
1953
1954 LIBTEST_API int STDCALL 
1955 mono_test_marshal_pass_return_custom_null_in_delegate (PassReturnPtrDelegate del)
1956 {
1957         void *ptr = del (NULL);
1958
1959         return (ptr == NULL) ? 15 : 0;
1960 }
1961
1962 typedef void (STDCALL *CustomOutParamDelegate) (void **pptr);
1963
1964 LIBTEST_API int STDCALL 
1965 mono_test_marshal_custom_out_param_delegate (CustomOutParamDelegate del)
1966 {
1967         void* pptr = del;
1968
1969         del (&pptr);
1970
1971         if(pptr != NULL)
1972                 return 1;
1973
1974         return 0;
1975 }
1976
1977 typedef int (STDCALL *ReturnEnumDelegate) (int e);
1978
1979 LIBTEST_API int STDCALL 
1980 mono_test_marshal_return_enum_delegate (ReturnEnumDelegate func)
1981 {
1982         return func (1);
1983 }
1984
1985 typedef struct {
1986         int a, b, c;
1987         gint64 d;
1988 } BlittableStruct;
1989         
1990 typedef BlittableStruct (STDCALL *SimpleDelegate10) (BlittableStruct ss);
1991
1992 LIBTEST_API int STDCALL 
1993 mono_test_marshal_blittable_struct_delegate (SimpleDelegate10 delegate)
1994 {
1995         BlittableStruct ss, res;
1996
1997         ss.a = 1;
1998         ss.b = 2;
1999         ss.c = 3;
2000         ss.d = 55;
2001
2002         res = delegate (ss);
2003         if (! ((res.a == -1) && (res.b == -2) && (res.c == -3) && (res.d == -55)))
2004                 return 1;
2005
2006         return 0;
2007 }
2008
2009 LIBTEST_API int STDCALL 
2010 mono_test_stdcall_name_mangling (int a, int b, int c)
2011 {
2012         return a + b + c;
2013 }
2014
2015 LIBTEST_API int
2016 mono_test_stdcall_mismatch_1 (int a, int b, int c)
2017 {
2018         return a + b + c;
2019 }
2020
2021 LIBTEST_API int STDCALL
2022 mono_test_stdcall_mismatch_2 (int a, int b, int c)
2023 {
2024         return a + b + c;
2025 }
2026
2027 /*
2028  * PASSING AND RETURNING SMALL STRUCTURES FROM DELEGATES TESTS
2029  */
2030
2031 typedef struct {
2032         int i;
2033 } SmallStruct1;
2034         
2035 typedef SmallStruct1 (STDCALL *SmallStructDelegate1) (SmallStruct1 ss);
2036
2037 LIBTEST_API int STDCALL 
2038 mono_test_marshal_small_struct_delegate1 (SmallStructDelegate1 delegate)
2039 {
2040         SmallStruct1 ss, res;
2041
2042         ss.i = 1;
2043
2044         res = delegate (ss);
2045         if (! (res.i == -1))
2046                 return 1;
2047
2048         return 0;
2049 }
2050
2051 typedef struct {
2052         gint16 i, j;
2053 } SmallStruct2;
2054         
2055 typedef SmallStruct2 (STDCALL *SmallStructDelegate2) (SmallStruct2 ss);
2056
2057 LIBTEST_API int STDCALL 
2058 mono_test_marshal_small_struct_delegate2 (SmallStructDelegate2 delegate)
2059 {
2060         SmallStruct2 ss, res;
2061
2062         ss.i = 2;
2063         ss.j = 3;
2064
2065         res = delegate (ss);
2066         if (! ((res.i == -2) && (res.j == -3)))
2067                 return 1;
2068
2069         return 0;
2070 }
2071
2072 typedef struct {
2073         gint16 i;
2074         gint8 j;
2075 } SmallStruct3;
2076         
2077 typedef SmallStruct3 (STDCALL *SmallStructDelegate3) (SmallStruct3 ss);
2078
2079 LIBTEST_API int STDCALL 
2080 mono_test_marshal_small_struct_delegate3 (SmallStructDelegate3 delegate)
2081 {
2082         SmallStruct3 ss, res;
2083
2084         ss.i = 1;
2085         ss.j = 2;
2086
2087         res = delegate (ss);
2088         if (! ((res.i == -1) && (res.j == -2)))
2089                 return 1;
2090
2091         return 0;
2092 }
2093
2094 typedef struct {
2095         gint16 i;
2096 } SmallStruct4;
2097         
2098 typedef SmallStruct4 (STDCALL *SmallStructDelegate4) (SmallStruct4 ss);
2099
2100 LIBTEST_API int STDCALL 
2101 mono_test_marshal_small_struct_delegate4 (SmallStructDelegate4 delegate)
2102 {
2103         SmallStruct4 ss, res;
2104
2105         ss.i = 1;
2106
2107         res = delegate (ss);
2108         if (! (res.i == -1))
2109                 return 1;
2110
2111         return 0;
2112 }
2113
2114 typedef struct {
2115         gint64 i;
2116 } SmallStruct5;
2117         
2118 typedef SmallStruct5 (STDCALL *SmallStructDelegate5) (SmallStruct5 ss);
2119
2120 LIBTEST_API int STDCALL 
2121 mono_test_marshal_small_struct_delegate5 (SmallStructDelegate5 delegate)
2122 {
2123         SmallStruct5 ss, res;
2124
2125         ss.i = 5;
2126
2127         res = delegate (ss);
2128         if (! (res.i == -5))
2129                 return 1;
2130
2131         return 0;
2132 }
2133
2134 typedef struct {
2135         int i, j;
2136 } SmallStruct6;
2137         
2138 typedef SmallStruct6 (STDCALL *SmallStructDelegate6) (SmallStruct6 ss);
2139
2140 LIBTEST_API int STDCALL 
2141 mono_test_marshal_small_struct_delegate6 (SmallStructDelegate6 delegate)
2142 {
2143         SmallStruct6 ss, res;
2144
2145         ss.i = 1;
2146         ss.j = 2;
2147
2148         res = delegate (ss);
2149         if (! ((res.i == -1) && (res.j == -2)))
2150                 return 1;
2151
2152         return 0;
2153 }
2154
2155 typedef struct {
2156         int i;
2157         gint16 j;
2158 } SmallStruct7;
2159         
2160 typedef SmallStruct7 (STDCALL *SmallStructDelegate7) (SmallStruct7 ss);
2161
2162 LIBTEST_API int STDCALL 
2163 mono_test_marshal_small_struct_delegate7 (SmallStructDelegate7 delegate)
2164 {
2165         SmallStruct7 ss, res;
2166
2167         ss.i = 1;
2168         ss.j = 2;
2169
2170         res = delegate (ss);
2171         if (! ((res.i == -1) && (res.j == -2)))
2172                 return 1;
2173
2174         return 0;
2175 }
2176
2177 typedef struct {
2178         float i;
2179 } SmallStruct8;
2180         
2181 typedef SmallStruct8 (STDCALL *SmallStructDelegate8) (SmallStruct8 ss);
2182
2183 LIBTEST_API int STDCALL 
2184 mono_test_marshal_small_struct_delegate8 (SmallStructDelegate8 delegate)
2185 {
2186         SmallStruct8 ss, res;
2187
2188         ss.i = 1.0;
2189
2190         res = delegate (ss);
2191         if (! ((res.i == -1.0)))
2192                 return 1;
2193
2194         return 0;
2195 }
2196
2197 typedef struct {
2198         double i;
2199 } SmallStruct9;
2200         
2201 typedef SmallStruct9 (STDCALL *SmallStructDelegate9) (SmallStruct9 ss);
2202
2203 LIBTEST_API int STDCALL 
2204 mono_test_marshal_small_struct_delegate9 (SmallStructDelegate9 delegate)
2205 {
2206         SmallStruct9 ss, res;
2207
2208         ss.i = 1.0;
2209
2210         res = delegate (ss);
2211         if (! ((res.i == -1.0)))
2212                 return 1;
2213
2214         return 0;
2215 }
2216
2217 typedef struct {
2218         float i, j;
2219 } SmallStruct10;
2220         
2221 typedef SmallStruct10 (STDCALL *SmallStructDelegate10) (SmallStruct10 ss);
2222
2223 LIBTEST_API int STDCALL 
2224 mono_test_marshal_small_struct_delegate10 (SmallStructDelegate10 delegate)
2225 {
2226         SmallStruct10 ss, res;
2227
2228         ss.i = 1.0;
2229         ss.j = 2.0;
2230
2231         res = delegate (ss);
2232         if (! ((res.i == -1.0) && (res.j == -2.0)))
2233                 return 1;
2234
2235         return 0;
2236 }
2237
2238 typedef struct {
2239         float i;
2240         int j;
2241 } SmallStruct11;
2242         
2243 typedef SmallStruct11 (STDCALL *SmallStructDelegate11) (SmallStruct11 ss);
2244
2245 LIBTEST_API int STDCALL 
2246 mono_test_marshal_small_struct_delegate11 (SmallStructDelegate11 delegate)
2247 {
2248         SmallStruct11 ss, res;
2249
2250         ss.i = 1.0;
2251         ss.j = 2;
2252
2253         res = delegate (ss);
2254         if (! ((res.i == -1.0) && (res.j == -2)))
2255                 return 1;
2256
2257         return 0;
2258 }
2259
2260 typedef int (STDCALL *ArrayDelegate) (int i, char *j, void *arr);
2261
2262 LIBTEST_API int STDCALL 
2263 mono_test_marshal_array_delegate (void *arr, int len, ArrayDelegate del)
2264 {
2265         return del (len, NULL, arr);
2266 }
2267
2268 typedef int (STDCALL *ArrayDelegateLong) (gint64 i, char *j, void *arr);
2269
2270 LIBTEST_API int STDCALL 
2271 mono_test_marshal_array_delegate_long (void *arr, gint64 len, ArrayDelegateLong del)
2272 {
2273         return del (len, NULL, arr);
2274 }
2275
2276 LIBTEST_API int STDCALL 
2277 mono_test_marshal_out_array_delegate (int *arr, int len, ArrayDelegate del)
2278 {
2279         del (len, NULL, arr);
2280
2281         if ((arr [0] != 1) || (arr [1] != 2))
2282                 return 1;
2283         else
2284                 return 0;
2285 }
2286
2287 typedef gunichar2* (STDCALL *UnicodeStringDelegate) (gunichar2 *message);
2288
2289 LIBTEST_API int STDCALL 
2290 mono_test_marshal_return_unicode_string_delegate (UnicodeStringDelegate del)
2291 {
2292         const char m[] = "abcdef";
2293         gunichar2 *s2, *res;
2294         glong len;
2295
2296         s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
2297
2298         res = del (s2);
2299
2300         marshal_free (res);
2301
2302         return 0;
2303 }
2304
2305 LIBTEST_API int STDCALL 
2306 mono_test_marshal_out_string_array_delegate (char **arr, int len, ArrayDelegate del)
2307 {
2308         del (len, NULL, arr);
2309
2310         if (!strcmp (arr [0], "ABC") && !strcmp (arr [1], "DEF"))
2311                 return 0;
2312         else
2313                 return 1;
2314 }
2315
2316 typedef int (*CdeclDelegate) (int i, int j);
2317
2318 LIBTEST_API int STDCALL 
2319 mono_test_marshal_cdecl_delegate (CdeclDelegate del)
2320 {
2321         int i;
2322
2323         for (i = 0; i < 1000; ++i)
2324                 del (1, 2);
2325
2326         return 0;
2327 }
2328
2329 typedef char** (STDCALL *ReturnStringArrayDelegate) (int i);
2330
2331 LIBTEST_API int STDCALL 
2332 mono_test_marshal_return_string_array_delegate (ReturnStringArrayDelegate d)
2333 {
2334         char **arr = d (2);
2335         int res;
2336
2337         if (arr == NULL)
2338                 return 3;
2339
2340         if (strcmp (arr [0], "ABC") || strcmp (arr [1], "DEF"))
2341                 res = 1;
2342         else
2343                 res = 0;
2344
2345         marshal_free (arr);
2346
2347         return res;
2348 }
2349
2350 typedef int (STDCALL *ByrefStringDelegate) (char **s);
2351
2352 LIBTEST_API int STDCALL 
2353 mono_test_marshal_byref_string_delegate (ByrefStringDelegate d)
2354 {
2355         char *s = (char*)"ABC";
2356         int res;
2357
2358         res = d (&s);
2359         if (res != 0)
2360                 return res;
2361
2362         if (!strcmp (s, "DEF"))
2363                 res = 0;
2364         else
2365                 res = 2;
2366
2367         marshal_free (s);
2368
2369         return res;
2370 }
2371
2372 LIBTEST_API int STDCALL 
2373 add_delegate (int i, int j)
2374 {
2375         return i + j;
2376 }
2377
2378 LIBTEST_API gpointer STDCALL 
2379 mono_test_marshal_return_fnptr (void)
2380 {
2381         return &add_delegate;
2382 }
2383
2384 LIBTEST_API int STDCALL 
2385 mono_xr (int code)
2386 {
2387         printf ("codigo %x\n", code);
2388         return code + 1234;
2389 }
2390
2391 typedef struct {
2392         int handle;
2393 } HandleRef;
2394
2395 LIBTEST_API HandleRef STDCALL 
2396 mono_xr_as_handle (int code)
2397 {
2398         HandleRef ref;
2399
2400         memset (&ref, 0, sizeof (ref));
2401
2402         return ref;
2403 }
2404  
2405 typedef struct {
2406         int   a;
2407         void *handle1;
2408         void *handle2;
2409         int   b;
2410 } HandleStructs;
2411
2412 LIBTEST_API int STDCALL 
2413 mono_safe_handle_struct_ref (HandleStructs *x)
2414 {
2415         printf ("Dingus Ref! \n");
2416         printf ("Values: %d %d %p %p\n", x->a, x->b, x->handle1, x->handle2);
2417         if (x->a != 1234)
2418                 return 1;
2419         if (x->b != 8743)
2420                 return 2;
2421
2422         if (x->handle1 != (void*) 0x7080feed)
2423                 return 3;
2424
2425         if (x->handle2 != (void*) 0x1234abcd)
2426                 return 4;
2427
2428         return 0xf00d;
2429 }
2430
2431 LIBTEST_API int STDCALL 
2432 mono_safe_handle_struct (HandleStructs x)
2433 {
2434         printf ("Dingus Standard! \n");
2435         printf ("Values: %d %d %p %p\n", x.a, x.b, x.handle1, x.handle2);
2436         if (x.a != 1234)
2437                 return 1;
2438         if (x.b != 8743)
2439                 return 2;
2440
2441         if (x.handle1 != (void*) 0x7080feed)
2442                 return 3;
2443
2444         if (x.handle2 != (void*) 0x1234abcd)
2445                 return 4;
2446         
2447         return 0xf00f;
2448 }
2449
2450 typedef struct {
2451         void *a;
2452 } TrivialHandle;
2453
2454 LIBTEST_API int STDCALL 
2455 mono_safe_handle_struct_simple (TrivialHandle x)
2456 {
2457         printf ("The value is %p\n", x.a);
2458         return ((int)(gsize)x.a) * 2;
2459 }
2460
2461 LIBTEST_API int STDCALL 
2462 mono_safe_handle_return (void)
2463 {
2464         return 0x1000f00d;
2465 }
2466
2467 LIBTEST_API void STDCALL
2468 mono_safe_handle_ref (void **handle)
2469 {
2470         if (*handle != 0){
2471                 *handle = (void *) 0xbad;
2472                 return;
2473         }
2474
2475         *handle = (void *) 0x800d;
2476 }
2477
2478 LIBTEST_API double STDCALL
2479 mono_test_marshal_date_time (double d, double *d2)
2480 {
2481         *d2 = d;
2482         return d;
2483 }
2484
2485 /*
2486  * COM INTEROP TESTS
2487  */
2488
2489 #ifndef WIN32
2490
2491 typedef struct {
2492         guint16 vt;
2493         guint16 wReserved1;
2494         guint16 wReserved2;
2495         guint16 wReserved3;
2496         union {
2497                 gint64 llVal;
2498                 gint32 lVal;
2499                 guint8  bVal;
2500                 gint16 iVal;
2501                 float  fltVal;
2502                 double dblVal;
2503                 gint16 boolVal;
2504                 gunichar2* bstrVal;
2505                 gint8 cVal;
2506                 guint16 uiVal;
2507                 guint32 ulVal;
2508                 guint64 ullVal;
2509                 gpointer byref;
2510                 struct {
2511                         gpointer pvRecord;
2512                         gpointer pRecInfo;
2513                 };
2514         };
2515 } VARIANT;
2516
2517 typedef enum {
2518         VARIANT_TRUE = -1,
2519         VARIANT_FALSE = 0
2520 } VariantBool;
2521
2522 typedef enum {
2523         VT_EMPTY = 0,
2524         VT_NULL = 1,
2525         VT_I2 = 2,
2526         VT_I4 = 3,
2527         VT_R4 = 4,
2528         VT_R8 = 5,
2529         VT_CY = 6,
2530         VT_DATE = 7,
2531         VT_BSTR = 8,
2532         VT_DISPATCH = 9,
2533         VT_ERROR = 10,
2534         VT_BOOL = 11,
2535         VT_VARIANT = 12,
2536         VT_UNKNOWN = 13,
2537         VT_DECIMAL = 14,
2538         VT_I1 = 16,
2539         VT_UI1 = 17,
2540         VT_UI2 = 18,
2541         VT_UI4 = 19,
2542         VT_I8 = 20,
2543         VT_UI8 = 21,
2544         VT_INT = 22,
2545         VT_UINT = 23,
2546         VT_VOID = 24,
2547         VT_HRESULT = 25,
2548         VT_PTR = 26,
2549         VT_SAFEARRAY = 27,
2550         VT_CARRAY = 28,
2551         VT_USERDEFINED = 29,
2552         VT_LPSTR = 30,
2553         VT_LPWSTR = 31,
2554         VT_RECORD = 36,
2555         VT_FILETIME = 64,
2556         VT_BLOB = 65,
2557         VT_STREAM = 66,
2558         VT_STORAGE = 67,
2559         VT_STREAMED_OBJECT = 68,
2560         VT_STORED_OBJECT = 69,
2561         VT_BLOB_OBJECT = 70,
2562         VT_CF = 71,
2563         VT_CLSID = 72,
2564         VT_VECTOR = 4096,
2565         VT_ARRAY = 8192,
2566         VT_BYREF = 16384
2567 } VarEnum;
2568
2569 void VariantInit(VARIANT* vt)
2570 {
2571         vt->vt = VT_EMPTY;
2572 }
2573
2574 typedef struct
2575 {
2576         guint32 a;
2577         guint16 b;
2578         guint16 c;
2579         guint8 d[8];
2580 } GUID;
2581
2582 #define S_OK 0
2583
2584 #endif
2585
2586 LIBTEST_API int STDCALL 
2587 mono_test_marshal_bstr_in(gunichar2* bstr)
2588 {
2589         gint32 result = 0;
2590         gchar* bstr_utf8 = g_utf16_to_utf8 (bstr, -1, NULL, NULL, NULL);
2591         result = strcmp("mono_test_marshal_bstr_in", bstr_utf8);
2592         g_free(bstr_utf8);
2593         if (result == 0)
2594                 return 0;
2595         return 1;
2596 }
2597
2598 LIBTEST_API int STDCALL 
2599 mono_test_marshal_bstr_out(gunichar2** bstr)
2600 {
2601         *bstr = marshal_bstr_alloc ("mono_test_marshal_bstr_out");
2602         return 0;
2603 }
2604
2605 LIBTEST_API int STDCALL 
2606 mono_test_marshal_bstr_in_null(gunichar2* bstr)
2607 {
2608         if (!bstr)
2609                 return 0;
2610         return 1;
2611 }
2612
2613 LIBTEST_API int STDCALL 
2614 mono_test_marshal_bstr_out_null(gunichar2** bstr)
2615 {
2616         *bstr = NULL;
2617         return 0;
2618 }
2619
2620 LIBTEST_API int STDCALL 
2621 mono_test_marshal_variant_in_sbyte(VARIANT variant)
2622 {
2623         if (variant.vt == VT_I1 && variant.cVal == 100)
2624                 return 0;
2625         return 1;
2626 }
2627
2628 LIBTEST_API int STDCALL 
2629 mono_test_marshal_variant_in_byte(VARIANT variant)
2630 {
2631         if (variant.vt == VT_UI1 && variant.bVal == 100)
2632                 return 0;
2633         return 1;
2634 }
2635
2636 LIBTEST_API int STDCALL 
2637 mono_test_marshal_variant_in_short(VARIANT variant)
2638 {
2639         if (variant.vt == VT_I2 && variant.iVal == 314)
2640                 return 0;
2641         return 1;
2642 }
2643
2644 LIBTEST_API int STDCALL 
2645 mono_test_marshal_variant_in_ushort(VARIANT variant)
2646 {
2647         if (variant.vt == VT_UI2 && variant.uiVal == 314)
2648                 return 0;
2649         return 1;
2650 }
2651
2652 LIBTEST_API int STDCALL 
2653 mono_test_marshal_variant_in_int(VARIANT variant)
2654 {
2655         if (variant.vt == VT_I4 && variant.lVal == 314)
2656                 return 0;
2657         return 1;
2658 }
2659
2660 LIBTEST_API int STDCALL 
2661 mono_test_marshal_variant_in_uint(VARIANT variant)
2662 {
2663         if (variant.vt == VT_UI4 && variant.ulVal == 314)
2664                 return 0;
2665         return 1;
2666 }
2667
2668 LIBTEST_API int STDCALL 
2669 mono_test_marshal_variant_in_long(VARIANT variant)
2670 {
2671         if (variant.vt == VT_I8 && variant.llVal == 314)
2672                 return 0;
2673         return 1;
2674 }
2675
2676 LIBTEST_API int STDCALL 
2677 mono_test_marshal_variant_in_ulong(VARIANT variant)
2678 {
2679         if (variant.vt == VT_UI8 && variant.ullVal == 314)
2680                 return 0;
2681         return 1;
2682 }
2683
2684 LIBTEST_API int STDCALL 
2685 mono_test_marshal_variant_in_float(VARIANT variant)
2686 {
2687         if (variant.vt == VT_R4 && (variant.fltVal - 3.14)/3.14 < .001)
2688                 return 0;
2689         return 1;
2690 }
2691
2692 LIBTEST_API int STDCALL 
2693 mono_test_marshal_variant_in_double(VARIANT variant)
2694 {
2695         if (variant.vt == VT_R8 && (variant.dblVal - 3.14)/3.14 < .001)
2696                 return 0;
2697         return 1;
2698 }
2699
2700 LIBTEST_API int STDCALL 
2701 mono_test_marshal_variant_in_bstr(VARIANT variant)
2702 {
2703         gint32 result = 0;
2704         gchar* bstr_utf8 = g_utf16_to_utf8 (variant.bstrVal, -1, NULL, NULL, NULL);
2705         result = strcmp("PI", bstr_utf8);
2706         g_free(bstr_utf8);
2707
2708         if (variant.vt == VT_BSTR && !result)
2709                 return 0;
2710         return 1;
2711 }
2712
2713 LIBTEST_API int STDCALL 
2714 mono_test_marshal_variant_in_bool_true (VARIANT variant)
2715 {
2716         if (variant.vt == VT_BOOL && variant.boolVal == VARIANT_TRUE)
2717                 return 0;
2718         return 1;
2719 }
2720
2721 LIBTEST_API int STDCALL 
2722 mono_test_marshal_variant_in_bool_false (VARIANT variant)
2723 {
2724         if (variant.vt == VT_BOOL && variant.boolVal == VARIANT_FALSE)
2725                 return 0;
2726         return 1;
2727 }
2728
2729 LIBTEST_API int STDCALL 
2730 mono_test_marshal_variant_out_sbyte(VARIANT* variant)
2731 {
2732         variant->vt = VT_I1;
2733         variant->cVal = 100;
2734
2735         return 0;
2736 }
2737
2738 LIBTEST_API int STDCALL 
2739 mono_test_marshal_variant_out_sbyte_byref(VARIANT* variant)
2740 {
2741         variant->vt = VT_I1|VT_BYREF;
2742         variant->byref = marshal_alloc(1);
2743         *((gint8*)variant->byref) = 100;
2744
2745         return 0;
2746 }
2747
2748 LIBTEST_API int STDCALL 
2749 mono_test_marshal_variant_out_byte(VARIANT* variant)
2750 {       
2751         variant->vt = VT_UI1;
2752         variant->bVal = 100;
2753
2754         return 0;
2755 }
2756
2757 LIBTEST_API int STDCALL 
2758 mono_test_marshal_variant_out_byte_byref(VARIANT* variant)
2759 {       
2760         variant->vt = VT_UI1|VT_BYREF;
2761         variant->byref = marshal_alloc(1);
2762         *((gint8*)variant->byref) = 100;
2763
2764         return 0;
2765 }
2766
2767 LIBTEST_API int STDCALL 
2768 mono_test_marshal_variant_out_short(VARIANT* variant)
2769 {
2770         variant->vt = VT_I2;
2771         variant->iVal = 314;
2772
2773         return 0;
2774 }
2775
2776 LIBTEST_API int STDCALL 
2777 mono_test_marshal_variant_out_short_byref(VARIANT* variant)
2778 {
2779         variant->vt = VT_I2|VT_BYREF;
2780         variant->byref = marshal_alloc(2);
2781         *((gint16*)variant->byref) = 314;
2782
2783         return 0;
2784 }
2785
2786 LIBTEST_API int STDCALL 
2787 mono_test_marshal_variant_out_ushort(VARIANT* variant)
2788 {
2789         variant->vt = VT_UI2;
2790         variant->uiVal = 314;
2791
2792         return 0;
2793 }
2794
2795 LIBTEST_API int STDCALL 
2796 mono_test_marshal_variant_out_ushort_byref(VARIANT* variant)
2797 {
2798         variant->vt = VT_UI2|VT_BYREF;
2799         variant->byref = marshal_alloc(2);
2800         *((guint16*)variant->byref) = 314;
2801
2802         return 0;
2803 }
2804
2805 LIBTEST_API int STDCALL 
2806 mono_test_marshal_variant_out_int(VARIANT* variant)
2807 {
2808         variant->vt = VT_I4;
2809         variant->lVal = 314;
2810
2811         return 0;
2812 }
2813
2814 LIBTEST_API int STDCALL 
2815 mono_test_marshal_variant_out_int_byref(VARIANT* variant)
2816 {
2817         variant->vt = VT_I4|VT_BYREF;
2818         variant->byref = marshal_alloc(4);
2819         *((gint32*)variant->byref) = 314;
2820
2821         return 0;
2822 }
2823
2824 LIBTEST_API int STDCALL 
2825 mono_test_marshal_variant_out_uint(VARIANT* variant)
2826 {
2827         variant->vt = VT_UI4;
2828         variant->ulVal = 314;
2829
2830         return 0;
2831 }
2832
2833 LIBTEST_API int STDCALL 
2834 mono_test_marshal_variant_out_uint_byref(VARIANT* variant)
2835 {
2836         variant->vt = VT_UI4|VT_BYREF;
2837         variant->byref = marshal_alloc(4);
2838         *((guint32*)variant->byref) = 314;
2839
2840         return 0;
2841 }
2842
2843 LIBTEST_API int STDCALL 
2844 mono_test_marshal_variant_out_long(VARIANT* variant)
2845 {
2846         variant->vt = VT_I8;
2847         variant->llVal = 314;
2848
2849         return 0;
2850 }
2851
2852 LIBTEST_API int STDCALL 
2853 mono_test_marshal_variant_out_long_byref(VARIANT* variant)
2854 {
2855         variant->vt = VT_I8|VT_BYREF;
2856         variant->byref = marshal_alloc(8);
2857         *((gint64*)variant->byref) = 314;
2858
2859         return 0;
2860 }
2861
2862 LIBTEST_API int STDCALL 
2863 mono_test_marshal_variant_out_ulong(VARIANT* variant)
2864 {
2865         variant->vt = VT_UI8;
2866         variant->ullVal = 314;
2867
2868         return 0;
2869 }
2870
2871 LIBTEST_API int STDCALL 
2872 mono_test_marshal_variant_out_ulong_byref(VARIANT* variant)
2873 {
2874         variant->vt = VT_UI8|VT_BYREF;
2875         variant->byref = marshal_alloc(8);
2876         *((guint64*)variant->byref) = 314;
2877
2878         return 0;
2879 }
2880
2881 LIBTEST_API int STDCALL 
2882 mono_test_marshal_variant_out_float(VARIANT* variant)
2883 {
2884         variant->vt = VT_R4;
2885         variant->fltVal = 3.14;
2886
2887         return 0;
2888 }
2889
2890 LIBTEST_API int STDCALL 
2891 mono_test_marshal_variant_out_float_byref(VARIANT* variant)
2892 {
2893         variant->vt = VT_R4|VT_BYREF;
2894         variant->byref = marshal_alloc(4);
2895         *((float*)variant->byref) = 3.14;
2896
2897         return 0;
2898 }
2899
2900 LIBTEST_API int STDCALL 
2901 mono_test_marshal_variant_out_double(VARIANT* variant)
2902 {
2903         variant->vt = VT_R8;
2904         variant->dblVal = 3.14;
2905
2906         return 0;
2907 }
2908
2909 LIBTEST_API int STDCALL 
2910 mono_test_marshal_variant_out_double_byref(VARIANT* variant)
2911 {
2912         variant->vt = VT_R8|VT_BYREF;
2913         variant->byref = marshal_alloc(8);
2914         *((double*)variant->byref) = 3.14;
2915
2916         return 0;
2917 }
2918
2919 LIBTEST_API int STDCALL 
2920 mono_test_marshal_variant_out_bstr(VARIANT* variant)
2921 {
2922         variant->vt = VT_BSTR;
2923         variant->bstrVal = marshal_bstr_alloc("PI");
2924
2925         return 0;
2926 }
2927
2928 LIBTEST_API int STDCALL 
2929 mono_test_marshal_variant_out_bstr_byref(VARIANT* variant)
2930 {
2931         variant->vt = VT_BSTR|VT_BYREF;
2932         variant->byref = marshal_alloc(sizeof(gpointer));
2933         *((gunichar**)variant->byref) = (gunichar*)marshal_bstr_alloc("PI");
2934
2935         return 0;
2936 }
2937
2938 LIBTEST_API int STDCALL 
2939 mono_test_marshal_variant_out_bool_true (VARIANT* variant)
2940 {
2941         variant->vt = VT_BOOL;
2942         variant->boolVal = VARIANT_TRUE;
2943
2944         return 0;
2945 }
2946
2947 LIBTEST_API int STDCALL 
2948 mono_test_marshal_variant_out_bool_true_byref (VARIANT* variant)
2949 {
2950         variant->vt = VT_BOOL|VT_BYREF;
2951         variant->byref = marshal_alloc(2);
2952         *((gint16*)variant->byref) = VARIANT_TRUE;
2953
2954         return 0;
2955 }
2956
2957 LIBTEST_API int STDCALL 
2958 mono_test_marshal_variant_out_bool_false (VARIANT* variant)
2959 {
2960         variant->vt = VT_BOOL;
2961         variant->boolVal = VARIANT_FALSE;
2962
2963         return 0;
2964 }
2965
2966 LIBTEST_API int STDCALL 
2967 mono_test_marshal_variant_out_bool_false_byref (VARIANT* variant)
2968 {
2969         variant->vt = VT_BOOL|VT_BYREF;
2970         variant->byref = marshal_alloc(2);
2971         *((gint16*)variant->byref) = VARIANT_FALSE;
2972
2973         return 0;
2974 }
2975
2976 typedef int (STDCALL *VarFunc) (int vt, VARIANT variant);
2977 typedef int (STDCALL *VarRefFunc) (int vt, VARIANT* variant);
2978
2979 LIBTEST_API int STDCALL 
2980 mono_test_marshal_variant_in_sbyte_unmanaged(VarFunc func)
2981 {
2982         VARIANT vt;
2983         vt.vt = VT_I1;
2984         vt.cVal = -100;
2985         return func (VT_I1, vt);
2986 }
2987
2988 LIBTEST_API int STDCALL 
2989 mono_test_marshal_variant_in_byte_unmanaged(VarFunc func)
2990 {
2991         VARIANT vt;
2992         vt.vt = VT_UI1;
2993         vt.bVal = 100;
2994         return func (VT_UI1, vt);
2995 }
2996
2997 LIBTEST_API int STDCALL 
2998 mono_test_marshal_variant_in_short_unmanaged(VarFunc func)
2999 {
3000         VARIANT vt;
3001         vt.vt = VT_I2;
3002         vt.iVal = -100;
3003         return func (VT_I2, vt);
3004 }
3005
3006 LIBTEST_API int STDCALL 
3007 mono_test_marshal_variant_in_ushort_unmanaged(VarFunc func)
3008 {
3009         VARIANT vt;
3010         vt.vt = VT_UI2;
3011         vt.uiVal = 100;
3012         return func (VT_UI2, vt);
3013 }
3014
3015 LIBTEST_API int STDCALL 
3016 mono_test_marshal_variant_in_int_unmanaged(VarFunc func)
3017 {
3018         VARIANT vt;
3019         vt.vt = VT_I4;
3020         vt.lVal = -100;
3021         return func (VT_I4, vt);
3022 }
3023
3024 LIBTEST_API int STDCALL 
3025 mono_test_marshal_variant_in_uint_unmanaged(VarFunc func)
3026 {
3027         VARIANT vt;
3028         vt.vt = VT_UI4;
3029         vt.ulVal = 100;
3030         return func (VT_UI4, vt);
3031 }
3032
3033 LIBTEST_API int STDCALL 
3034 mono_test_marshal_variant_in_long_unmanaged(VarFunc func)
3035 {
3036         VARIANT vt;
3037         vt.vt = VT_I8;
3038         vt.llVal = -100;
3039         return func (VT_I8, vt);
3040 }
3041
3042 LIBTEST_API int STDCALL 
3043 mono_test_marshal_variant_in_ulong_unmanaged(VarFunc func)
3044 {
3045         VARIANT vt;
3046         vt.vt = VT_UI8;
3047         vt.ullVal = 100;
3048         return func (VT_UI8, vt);
3049 }
3050
3051 LIBTEST_API int STDCALL 
3052 mono_test_marshal_variant_in_float_unmanaged(VarFunc func)
3053 {
3054         VARIANT vt;
3055         vt.vt = VT_R4;
3056         vt.fltVal = 3.14;
3057         return func (VT_R4, vt);
3058 }
3059
3060 LIBTEST_API int STDCALL 
3061 mono_test_marshal_variant_in_double_unmanaged(VarFunc func)
3062 {
3063         VARIANT vt;
3064         vt.vt = VT_R8;
3065         vt.dblVal = 3.14;
3066         return func (VT_R8, vt);
3067 }
3068
3069 LIBTEST_API int STDCALL 
3070 mono_test_marshal_variant_in_bstr_unmanaged(VarFunc func)
3071 {
3072         VARIANT vt;
3073         vt.vt = VT_BSTR;
3074         vt.bstrVal = marshal_bstr_alloc("PI");
3075         return func (VT_BSTR, vt);
3076 }
3077
3078 LIBTEST_API int STDCALL 
3079 mono_test_marshal_variant_in_bool_true_unmanaged(VarFunc func)
3080 {
3081         VARIANT vt;
3082         vt.vt = VT_BOOL;
3083         vt.boolVal = VARIANT_TRUE;
3084         return func (VT_BOOL, vt);
3085 }
3086
3087 LIBTEST_API int STDCALL 
3088 mono_test_marshal_variant_in_bool_false_unmanaged(VarFunc func)
3089 {
3090         VARIANT vt;
3091         vt.vt = VT_BOOL;
3092         vt.boolVal = VARIANT_FALSE;
3093         return func (VT_BOOL, vt);
3094 }
3095
3096 LIBTEST_API int STDCALL 
3097 mono_test_marshal_variant_out_sbyte_unmanaged(VarRefFunc func)
3098 {
3099         VARIANT vt;
3100         VariantInit (&vt);
3101         func (VT_I1, &vt);
3102         if (vt.vt == VT_I1 && vt.cVal == -100)
3103                 return 0;
3104         return 1;
3105 }
3106
3107 LIBTEST_API int STDCALL 
3108 mono_test_marshal_variant_out_byte_unmanaged(VarRefFunc func)
3109 {
3110         VARIANT vt;
3111         VariantInit (&vt);
3112         func (VT_UI1, &vt);
3113         if (vt.vt == VT_UI1 && vt.bVal == 100)
3114                 return 0;
3115         return 1;
3116 }
3117
3118 LIBTEST_API int STDCALL 
3119 mono_test_marshal_variant_out_short_unmanaged(VarRefFunc func)
3120 {
3121         VARIANT vt;
3122         VariantInit (&vt);
3123         func (VT_I2, &vt);
3124         if (vt.vt == VT_I2 && vt.iVal == -100)
3125                 return 0;
3126         return 1;
3127 }
3128
3129 LIBTEST_API int STDCALL 
3130 mono_test_marshal_variant_out_ushort_unmanaged(VarRefFunc func)
3131 {
3132         VARIANT vt;
3133         VariantInit (&vt);
3134         func (VT_UI2, &vt);
3135         if (vt.vt == VT_UI2 && vt.uiVal == 100)
3136                 return 0;
3137         return 1;
3138 }
3139
3140 LIBTEST_API int STDCALL 
3141 mono_test_marshal_variant_out_int_unmanaged(VarRefFunc func)
3142 {
3143         VARIANT vt;
3144         VariantInit (&vt);
3145         func (VT_I4, &vt);
3146         if (vt.vt == VT_I4 && vt.lVal == -100)
3147                 return 0;
3148         return 1;
3149 }
3150
3151 LIBTEST_API int STDCALL 
3152 mono_test_marshal_variant_out_uint_unmanaged(VarRefFunc func)
3153 {
3154         VARIANT vt;
3155         VariantInit (&vt);
3156         func (VT_UI4, &vt);
3157         if (vt.vt == VT_UI4 && vt.ulVal == 100)
3158                 return 0;
3159         return 1;
3160 }
3161
3162 LIBTEST_API int STDCALL 
3163 mono_test_marshal_variant_out_long_unmanaged(VarRefFunc func)
3164 {
3165         VARIANT vt;
3166         VariantInit (&vt);
3167         func (VT_I8, &vt);
3168         if (vt.vt == VT_I8 && vt.llVal == -100)
3169                 return 0;
3170         return 1;
3171 }
3172
3173 LIBTEST_API int STDCALL 
3174 mono_test_marshal_variant_out_ulong_unmanaged(VarRefFunc func)
3175 {
3176         VARIANT vt;
3177         VariantInit (&vt);
3178         func (VT_UI8, &vt);
3179         if (vt.vt == VT_UI8 && vt.ullVal == 100)
3180                 return 0;
3181         return 1;
3182 }
3183
3184 LIBTEST_API int STDCALL 
3185 mono_test_marshal_variant_out_float_unmanaged(VarRefFunc func)
3186 {
3187         VARIANT vt;
3188         VariantInit (&vt);
3189         func (VT_R4, &vt);
3190         if (vt.vt == VT_R4 && fabs (vt.fltVal - 3.14f) < 1e-10)
3191                 return 0;
3192         return 1;
3193 }
3194
3195 LIBTEST_API int STDCALL 
3196 mono_test_marshal_variant_out_double_unmanaged(VarRefFunc func)
3197 {
3198         VARIANT vt;
3199         VariantInit (&vt);
3200         func (VT_R8, &vt);
3201         if (vt.vt == VT_R8 && fabs (vt.dblVal - 3.14) < 1e-10)
3202                 return 0;
3203         return 1;
3204 }
3205
3206 LIBTEST_API int STDCALL 
3207 mono_test_marshal_variant_out_bstr_unmanaged(VarRefFunc func)
3208 {
3209         VARIANT vt;
3210         gchar* bstr_utf8;
3211         gint32 result = 0;
3212
3213
3214         VariantInit (&vt);
3215         func (VT_BSTR, &vt);
3216         bstr_utf8 = g_utf16_to_utf8 (vt.bstrVal, -1, NULL, NULL, NULL);
3217         result = strcmp("PI", bstr_utf8);
3218         g_free(bstr_utf8);
3219         if (vt.vt == VT_BSTR && !result)
3220                 return 0;
3221         return 1;
3222 }
3223
3224 LIBTEST_API int STDCALL 
3225 mono_test_marshal_variant_out_bool_true_unmanaged(VarRefFunc func)
3226 {
3227         VARIANT vt;
3228         VariantInit (&vt);
3229         func (VT_BOOL, &vt);
3230         if (vt.vt == VT_BOOL && vt.boolVal == VARIANT_TRUE)
3231                 return 0;
3232         return 1;
3233 }
3234
3235 LIBTEST_API int STDCALL 
3236 mono_test_marshal_variant_out_bool_false_unmanaged(VarRefFunc func)
3237 {
3238         VARIANT vt;
3239         VariantInit (&vt);
3240         func (VT_BOOL, &vt);
3241         if (vt.vt == VT_BOOL && vt.boolVal == VARIANT_TRUE)
3242                 return 0;
3243         return 1;
3244 }
3245
3246 typedef struct MonoComObject MonoComObject;
3247
3248 typedef struct
3249 {
3250         int (STDCALL *QueryInterface)(MonoComObject* pUnk, gpointer riid, gpointer* ppv);
3251         int (STDCALL *AddRef)(MonoComObject* pUnk);
3252         int (STDCALL *Release)(MonoComObject* pUnk);
3253         int (STDCALL *get_ITest)(MonoComObject* pUnk, MonoComObject* *ppUnk);
3254         int (STDCALL *SByteIn)(MonoComObject* pUnk, char a);
3255         int (STDCALL *ByteIn)(MonoComObject* pUnk, unsigned char a);
3256         int (STDCALL *ShortIn)(MonoComObject* pUnk, short a);
3257         int (STDCALL *UShortIn)(MonoComObject* pUnk, unsigned short a);
3258         int (STDCALL *IntIn)(MonoComObject* pUnk, int a);
3259         int (STDCALL *UIntIn)(MonoComObject* pUnk, unsigned int a);
3260         int (STDCALL *LongIn)(MonoComObject* pUnk, gint64 a);
3261         int (STDCALL *ULongIn)(MonoComObject* pUnk, guint64 a);
3262         int (STDCALL *FloatIn)(MonoComObject* pUnk, float a);
3263         int (STDCALL *DoubleIn)(MonoComObject* pUnk, double a);
3264         int (STDCALL *ITestIn)(MonoComObject* pUnk, MonoComObject* pUnk2);
3265         int (STDCALL *ITestOut)(MonoComObject* pUnk, MonoComObject* *ppUnk);
3266 } MonoIUnknown;
3267
3268 struct MonoComObject
3269 {
3270         MonoIUnknown* vtbl;
3271         int m_ref;
3272 };
3273
3274 static GUID IID_ITest = {0, 0, 0, {0,0,0,0,0,0,0,1}};
3275 static GUID IID_IMonoUnknown = {0, 0, 0, {0xc0,0,0,0,0,0,0,0x46}};
3276 static GUID IID_IMonoDispatch = {0x00020400, 0, 0, {0xc0,0,0,0,0,0,0,0x46}};
3277
3278 LIBTEST_API int STDCALL
3279 MonoQueryInterface(MonoComObject* pUnk, gpointer riid, gpointer* ppv)
3280 {
3281
3282         *ppv = NULL;
3283         if (!memcmp(riid, &IID_IMonoUnknown, sizeof(GUID))) {
3284                 *ppv = pUnk;
3285                 return S_OK;
3286         }
3287         else if (!memcmp(riid, &IID_ITest, sizeof(GUID))) {
3288                 *ppv = pUnk;
3289                 return S_OK;
3290         }
3291         else if (!memcmp(riid, &IID_IMonoDispatch, sizeof(GUID))) {
3292                 *ppv = pUnk;
3293                 return S_OK;
3294         }
3295         return 0x80004002; //E_NOINTERFACE;
3296 }
3297
3298 LIBTEST_API int STDCALL 
3299 MonoAddRef(MonoComObject* pUnk)
3300 {
3301         return ++(pUnk->m_ref);
3302 }
3303
3304 LIBTEST_API int STDCALL 
3305 MonoRelease(MonoComObject* pUnk)
3306 {
3307         return --(pUnk->m_ref);
3308 }
3309
3310 LIBTEST_API int STDCALL 
3311 SByteIn(MonoComObject* pUnk, char a)
3312 {
3313         return S_OK;
3314 }
3315
3316 LIBTEST_API int STDCALL 
3317 ByteIn(MonoComObject* pUnk, unsigned char a)
3318 {
3319         return S_OK;
3320 }
3321
3322 LIBTEST_API int STDCALL 
3323 ShortIn(MonoComObject* pUnk, short a)
3324 {
3325         return S_OK;
3326 }
3327
3328 LIBTEST_API int STDCALL 
3329 UShortIn(MonoComObject* pUnk, unsigned short a)
3330 {
3331         return S_OK;
3332 }
3333
3334 LIBTEST_API int STDCALL 
3335 IntIn(MonoComObject* pUnk, int a)
3336 {
3337         return S_OK;
3338 }
3339
3340 LIBTEST_API int STDCALL 
3341 UIntIn(MonoComObject* pUnk, unsigned int a)
3342 {
3343         return S_OK;
3344 }
3345
3346 LIBTEST_API int STDCALL 
3347 LongIn(MonoComObject* pUnk, gint64 a)
3348 {
3349         return S_OK;
3350 }
3351
3352 LIBTEST_API int STDCALL 
3353 ULongIn(MonoComObject* pUnk, guint64 a)
3354 {
3355         return S_OK;
3356 }
3357
3358 LIBTEST_API int STDCALL 
3359 FloatIn(MonoComObject* pUnk, float a)
3360 {
3361         return S_OK;
3362 }
3363
3364 LIBTEST_API int STDCALL 
3365 DoubleIn(MonoComObject* pUnk, double a)
3366 {
3367         return S_OK;
3368 }
3369
3370 LIBTEST_API int STDCALL 
3371 ITestIn(MonoComObject* pUnk, MonoComObject *pUnk2)
3372 {
3373         return S_OK;
3374 }
3375
3376 LIBTEST_API int STDCALL 
3377 ITestOut(MonoComObject* pUnk, MonoComObject* *ppUnk)
3378 {
3379         return S_OK;
3380 }
3381
3382 static void create_com_object (MonoComObject** pOut);
3383
3384 LIBTEST_API int STDCALL 
3385 get_ITest(MonoComObject* pUnk, MonoComObject* *ppUnk)
3386 {
3387         create_com_object (ppUnk);
3388         return S_OK;
3389 }
3390
3391 static void create_com_object (MonoComObject** pOut)
3392 {
3393         *pOut = marshal_new0 (MonoComObject, 1);
3394         (*pOut)->vtbl = marshal_new0 (MonoIUnknown, 1);
3395
3396         (*pOut)->m_ref = 1;
3397         (*pOut)->vtbl->QueryInterface = MonoQueryInterface;
3398         (*pOut)->vtbl->AddRef = MonoAddRef;
3399         (*pOut)->vtbl->Release = MonoRelease;
3400         (*pOut)->vtbl->SByteIn = SByteIn;
3401         (*pOut)->vtbl->ByteIn = ByteIn;
3402         (*pOut)->vtbl->ShortIn = ShortIn;
3403         (*pOut)->vtbl->UShortIn = UShortIn;
3404         (*pOut)->vtbl->IntIn = IntIn;
3405         (*pOut)->vtbl->UIntIn = UIntIn;
3406         (*pOut)->vtbl->LongIn = LongIn;
3407         (*pOut)->vtbl->ULongIn = ULongIn;
3408         (*pOut)->vtbl->FloatIn = FloatIn;
3409         (*pOut)->vtbl->DoubleIn = DoubleIn;
3410         (*pOut)->vtbl->ITestIn = ITestIn;
3411         (*pOut)->vtbl->ITestOut = ITestOut;
3412         (*pOut)->vtbl->get_ITest = get_ITest;
3413 }
3414
3415 static MonoComObject* same_object = NULL;
3416
3417 LIBTEST_API int STDCALL 
3418 mono_test_marshal_com_object_create(MonoComObject* *pUnk)
3419 {
3420         create_com_object (pUnk);
3421
3422         if (!same_object)
3423                 same_object = *pUnk;
3424
3425         return 0;
3426 }
3427
3428 LIBTEST_API int STDCALL 
3429 mono_test_marshal_com_object_same(MonoComObject* *pUnk)
3430 {
3431         *pUnk = same_object;
3432
3433         return 0;
3434 }
3435
3436 LIBTEST_API int STDCALL 
3437 mono_test_marshal_com_object_destroy(MonoComObject *pUnk)
3438 {
3439         int ref = --(pUnk->m_ref);
3440         g_free(pUnk->vtbl);
3441         g_free(pUnk);
3442
3443         return ref;
3444 }
3445
3446 LIBTEST_API int STDCALL 
3447 mono_test_marshal_com_object_ref_count(MonoComObject *pUnk)
3448 {
3449         return pUnk->m_ref;
3450 }
3451
3452 LIBTEST_API int STDCALL 
3453 mono_test_marshal_ccw_itest (MonoComObject *pUnk)
3454 {
3455         int hr = 0;
3456         MonoComObject* pTest;
3457
3458         if (!pUnk)
3459                 return 1;
3460
3461         hr = pUnk->vtbl->SByteIn (pUnk, -100);
3462         if (hr != 0)
3463                 return 2;
3464         hr = pUnk->vtbl->ByteIn (pUnk, 100);
3465         if (hr != 0)
3466                 return 3;
3467         hr = pUnk->vtbl->ShortIn (pUnk, -100);
3468         if (hr != 0)
3469                 return 4;
3470         hr = pUnk->vtbl->UShortIn (pUnk, 100);
3471         if (hr != 0)
3472                 return 5;
3473         hr = pUnk->vtbl->IntIn (pUnk, -100);
3474         if (hr != 0)
3475                 return 6;
3476         hr = pUnk->vtbl->UIntIn (pUnk, 100);
3477         if (hr != 0)
3478                 return 7;
3479         hr = pUnk->vtbl->LongIn (pUnk, -100);
3480         if (hr != 0)
3481                 return 8;
3482         hr = pUnk->vtbl->ULongIn (pUnk, 100);
3483         if (hr != 0)
3484                 return 9;
3485         hr = pUnk->vtbl->FloatIn (pUnk, 3.14f);
3486         if (hr != 0)
3487                 return 10;
3488         hr = pUnk->vtbl->DoubleIn (pUnk, 3.14);
3489         if (hr != 0)
3490                 return 11;
3491         hr = pUnk->vtbl->ITestIn (pUnk, pUnk);
3492         if (hr != 0)
3493                 return 12;
3494         hr = pUnk->vtbl->ITestOut (pUnk, &pTest);
3495         if (hr != 0)
3496                 return 13;
3497
3498         return 0;
3499 }
3500
3501 /*
3502  * mono_method_get_unmanaged_thunk tests
3503  */
3504
3505 #if defined(__GNUC__) && ((defined(__i386__) && (defined(__linux__) || defined (__APPLE__)) || defined (__FreeBSD__) || defined(__OpenBSD__)) || (defined(__ppc__) && defined(__APPLE__)))
3506 #define ALIGN(size) __attribute__ ((aligned(size)))
3507 #else
3508 #define ALIGN(size)
3509 #endif
3510
3511
3512 /* thunks.cs:TestStruct */
3513 typedef struct _TestStruct {
3514         int A;
3515         double B;
3516 } TestStruct;
3517
3518 /* Searches for mono symbols in all loaded modules */
3519 static gpointer
3520 lookup_mono_symbol (const char *symbol_name)
3521 {
3522         gpointer symbol;
3523         if (g_module_symbol (g_module_open (NULL, G_MODULE_BIND_LAZY), symbol_name, &symbol))
3524                 return symbol;
3525         else
3526                 return NULL;
3527 }
3528
3529 LIBTEST_API gpointer STDCALL
3530 mono_test_marshal_lookup_symbol (const char *symbol_name)
3531 {
3532         return lookup_mono_symbol (symbol_name);
3533 }
3534
3535 /**
3536  * test_method_thunk:
3537  *
3538  * @test_id: the test number
3539  * @test_method_handle: MonoMethod* of the C# test method
3540  * @create_object_method_handle: MonoMethod* of thunks.cs:Test.CreateObject
3541  */
3542 LIBTEST_API int STDCALL  
3543 test_method_thunk (int test_id, gpointer test_method_handle, gpointer create_object_method_handle)
3544 {
3545         gpointer (*mono_method_get_unmanaged_thunk)(gpointer)
3546                 = lookup_mono_symbol ("mono_method_get_unmanaged_thunk");
3547
3548         gpointer (*mono_string_new_wrapper)(const char *)
3549                 = lookup_mono_symbol ("mono_string_new_wrapper");
3550
3551         char* (*mono_string_to_utf8)(gpointer)
3552                 = lookup_mono_symbol ("mono_string_to_utf8");
3553
3554         gpointer (*mono_object_unbox)(gpointer)
3555                 = lookup_mono_symbol ("mono_object_unbox");
3556
3557         gpointer test_method, ex = NULL;
3558         gpointer (STDCALL *CreateObject)(gpointer*);
3559
3560         if (!mono_method_get_unmanaged_thunk)
3561                 return 1;
3562
3563         test_method =  mono_method_get_unmanaged_thunk (test_method_handle);
3564         if (!test_method)
3565                 return 2;
3566
3567         CreateObject = mono_method_get_unmanaged_thunk (create_object_method_handle);
3568         if (!CreateObject)
3569                 return 3;
3570
3571
3572         switch (test_id) {
3573
3574         case 0: {
3575                 /* thunks.cs:Test.Test0 */
3576                 void (STDCALL *F)(gpointer*) = test_method;
3577                 F (&ex);
3578                 break;
3579         }
3580
3581         case 1: {
3582                 /* thunks.cs:Test.Test1 */
3583                 int (STDCALL *F)(gpointer*) = test_method;
3584                 if (F (&ex) != 42)
3585                         return 4;
3586                 break;
3587         }
3588
3589         case 2: {
3590                 /* thunks.cs:Test.Test2 */
3591                 gpointer (STDCALL *F)(gpointer, gpointer*) = test_method;
3592                 gpointer str = mono_string_new_wrapper ("foo");
3593                 if (str != F (str, &ex))
3594                         return 4;
3595                 break;
3596         }
3597
3598         case 3: {
3599                 /* thunks.cs:Test.Test3 */
3600                 gpointer (STDCALL *F)(gpointer, gpointer, gpointer*);
3601                 gpointer obj;
3602                 gpointer str;
3603
3604                 F = test_method;
3605                 obj = CreateObject (&ex);
3606                 str = mono_string_new_wrapper ("bar");
3607
3608                 if (str != F (obj, str, &ex))
3609                         return 4;
3610                 break;
3611         }
3612
3613         case 4: {
3614                 /* thunks.cs:Test.Test4 */
3615                 int (STDCALL *F)(gpointer, gpointer, int, gpointer*);
3616                 gpointer obj;
3617                 gpointer str;
3618
3619                 F = test_method;
3620                 obj = CreateObject (&ex);
3621                 str = mono_string_new_wrapper ("bar");
3622
3623                 if (42 != F (obj, str, 42, &ex))
3624                         return 4;
3625
3626                 break;
3627         }
3628
3629         case 5: {
3630                 /* thunks.cs:Test.Test5 */
3631                 int (STDCALL *F)(gpointer, gpointer, int, gpointer*);
3632                 gpointer obj;
3633                 gpointer str;
3634
3635                 F = test_method;
3636                 obj = CreateObject (&ex);
3637                 str = mono_string_new_wrapper ("bar");
3638
3639                 F (obj, str, 42, &ex);
3640                 if (!ex)
3641                     return 4;
3642
3643                 break;
3644         }
3645
3646         case 6: {
3647                 /* thunks.cs:Test.Test6 */
3648                 int (STDCALL *F)(gpointer, guint8, gint16, gint32, gint64, float, double,
3649                                  gpointer, gpointer*);
3650                 gpointer obj;
3651                 gpointer str = mono_string_new_wrapper ("Test6");
3652                 int res;
3653
3654                 F = test_method;
3655                 obj = CreateObject (&ex);
3656
3657                 res = F (obj, 254, 32700, -245378, 6789600, 3.1415, 3.1415, str, &ex);
3658                 if (ex)
3659                         return 4;
3660
3661                 if (!res)
3662                         return 5;
3663
3664                 break;
3665         }
3666
3667         case 7: {
3668                 /* thunks.cs:Test.Test7 */
3669                 gint64 (STDCALL *F)(gpointer*) = test_method;
3670                 if (F (&ex) != G_MAXINT64)
3671                         return 4;
3672                 break;
3673         }
3674
3675         case 8: {
3676                 /* thunks.cs:Test.Test8 */
3677                 void (STDCALL *F)(guint8*, gint16*, gint32*, gint64*, float*, double*,
3678                                  gpointer*, gpointer*);
3679
3680                 guint8 a1;
3681                 gint16 a2;
3682                 gint32 a3;
3683                 gint64 a4;
3684                 float a5;
3685                 double a6;
3686                 gpointer a7;
3687
3688                 F = test_method;
3689
3690                 F (&a1, &a2, &a3, &a4, &a5, &a6, &a7, &ex);
3691                 if (ex)
3692                         return 4;
3693
3694                 if (!(a1 == 254 &&
3695                       a2 == 32700 &&
3696                       a3 == -245378 &&
3697                       a4 == 6789600 &&
3698                       (fabs (a5 - 3.1415) < 0.001) &&
3699                       (fabs (a6 - 3.1415) < 0.001) &&
3700                       strcmp (mono_string_to_utf8 (a7), "Test8") == 0))
3701                         return 5;
3702
3703                 break;
3704         }
3705
3706         case 9: {
3707                 /* thunks.cs:Test.Test9 */
3708                 void (STDCALL *F)(guint8*, gint16*, gint32*, gint64*, float*, double*,
3709                                  gpointer*, gpointer*);
3710
3711                 guint8 a1;
3712                 gint16 a2;
3713                 gint32 a3;
3714                 gint64 a4;
3715                 float a5;
3716                 double a6;
3717                 gpointer a7;
3718
3719                 F = test_method;
3720
3721                 F (&a1, &a2, &a3, &a4, &a5, &a6, &a7, &ex);
3722                 if (!ex)
3723                         return 4;
3724
3725                 break;
3726         }
3727
3728         case 10: {
3729                 /* thunks.cs:Test.Test10 */
3730                 void (STDCALL *F)(gpointer*, gpointer*);
3731
3732                 gpointer obj1, obj2;
3733
3734                 obj1 = obj2 = CreateObject (&ex);
3735                 if (ex)
3736                         return 4;
3737
3738                 F = test_method;
3739
3740                 F (&obj1, &ex);
3741                 if (ex)
3742                         return 5;
3743
3744                 if (obj1 == obj2)
3745                         return 6;
3746
3747                 break;
3748         }
3749
3750         case 100: {
3751                 /* thunks.cs:TestStruct.Test0 */
3752                 int (STDCALL *F)(gpointer*, gpointer*);
3753
3754                 gpointer obj;
3755                 TestStruct *a1;
3756                 int res;
3757
3758                 obj = CreateObject (&ex);
3759                 if (ex)
3760                         return 4;
3761
3762                 if (!obj)
3763                         return 5;
3764
3765                 a1 = mono_object_unbox (obj);
3766                 if (!a1)
3767                         return 6;
3768
3769                 a1->A = 42;
3770                 a1->B = 3.1415;
3771
3772                 F = test_method;
3773
3774                 res = F (obj, &ex);
3775                 if (ex)
3776                         return 7;
3777
3778                 if (!res)
3779                         return 8;
3780
3781                 /* check whether the call was really by value */
3782                 if (a1->A != 42 || a1->B != 3.1415)
3783                         return 9;
3784
3785                 break;
3786         }
3787
3788         case 101: {
3789                 /* thunks.cs:TestStruct.Test1 */
3790                 void (STDCALL *F)(gpointer, gpointer*);
3791
3792                 TestStruct *a1;
3793                 gpointer obj;
3794
3795                 obj = CreateObject (&ex);
3796                 if (ex)
3797                         return 4;
3798
3799                 if (!obj)
3800                         return 5;
3801
3802                 a1 = mono_object_unbox (obj);
3803                 if (!a1)
3804                         return 6;
3805
3806                 F = test_method;
3807
3808                 F (obj, &ex);
3809                 if (ex)
3810                         return 7;
3811
3812                 if (a1->A != 42)
3813                         return 8;
3814
3815                 if (!fabs (a1->B - 3.1415) < 0.001)
3816                         return 9;
3817
3818                 break;
3819         }
3820
3821         case 102: {
3822                 /* thunks.cs:TestStruct.Test2 */
3823                 gpointer (STDCALL *F)(gpointer*);
3824
3825                 TestStruct *a1;
3826                 gpointer obj;
3827
3828                 F = test_method;
3829
3830                 obj = F (&ex);
3831                 if (ex)
3832                         return 4;
3833
3834                 if (!obj)
3835                         return 5;
3836
3837                 a1 = mono_object_unbox (obj);
3838
3839                 if (a1->A != 42)
3840                         return 5;
3841
3842                 if (!fabs (a1->B - 3.1415) < 0.001)
3843                         return 6;
3844
3845                 break;
3846         }
3847
3848         case 103: {
3849                 /* thunks.cs:TestStruct.Test3 */
3850                 void (STDCALL *F)(gpointer, gpointer*);
3851
3852                 TestStruct *a1;
3853                 gpointer obj;
3854
3855                 obj = CreateObject (&ex);
3856                 if (ex)
3857                         return 4;
3858
3859                 if (!obj)
3860                         return 5;
3861                 
3862                 a1 = mono_object_unbox (obj);
3863
3864                 if (!a1)
3865                         return 6;
3866
3867                 a1->A = 42;
3868                 a1->B = 3.1415;
3869
3870                 F = test_method;
3871
3872                 F (obj, &ex);
3873                 if (ex)
3874                         return 4;
3875
3876                 if (a1->A != 1)
3877                         return 5;
3878
3879                 if (a1->B != 17)
3880                         return 6;
3881
3882                 break;
3883         }
3884
3885         default:
3886                 return 9;
3887
3888         }
3889
3890         return 0;
3891 }
3892
3893 typedef struct 
3894 {
3895         char a;
3896 } winx64_struct1;
3897
3898 LIBTEST_API int STDCALL  
3899 mono_test_Winx64_struct1_in (winx64_struct1 var)
3900 {
3901         if (var.a != 123)
3902                 return 1;
3903         return 0;
3904 }
3905
3906 typedef struct
3907 {
3908         char a;
3909         char b;
3910 } winx64_struct2;
3911
3912 LIBTEST_API int STDCALL  
3913 mono_test_Winx64_struct2_in (winx64_struct2 var)
3914 {
3915         if (var.a != 4)
3916                 return 1;
3917         if (var.b != 5)
3918                 return 2;
3919         return 0;
3920 }
3921
3922
3923 typedef struct
3924 {
3925         char a;
3926         char b;
3927         short c;
3928 } winx64_struct3;
3929
3930 LIBTEST_API int STDCALL  
3931 mono_test_Winx64_struct3_in (winx64_struct3 var)
3932 {
3933         if (var.a != 4)
3934                 return 1;
3935         if (var.b != 5)
3936                 return 2;
3937         if (var.c != 0x1234)
3938                 return 3;
3939         return 0;
3940 }
3941
3942 typedef struct
3943 {
3944         char a;
3945         char b;
3946         short c;
3947         unsigned int d;
3948 } winx64_struct4;
3949
3950 LIBTEST_API int STDCALL  
3951 mono_test_Winx64_struct4_in (winx64_struct4 var)
3952 {
3953         if (var.a != 4)
3954                 return 1;
3955         if (var.b != 5)
3956                 return 2;
3957         if (var.c != 0x1234)
3958                 return 3;
3959         if (var.d != 0x87654321)
3960                 return 4;
3961         return 0;
3962 }
3963
3964 typedef struct
3965 {
3966         char a;
3967         char b;
3968         char c;
3969 } winx64_struct5;
3970
3971 LIBTEST_API int STDCALL  
3972 mono_test_Winx64_struct5_in (winx64_struct5 var)
3973 {
3974         if (var.a != 4)
3975                 return 1;
3976         if (var.b != 5)
3977                 return 2;
3978         if (var.c != 6)
3979                 return 3;
3980         return 0;
3981 }
3982
3983 typedef struct
3984 {
3985         winx64_struct1 a;
3986         short b;
3987         char c;
3988 } winx64_struct6;
3989
3990 LIBTEST_API int STDCALL  
3991 mono_test_Winx64_struct6_in (winx64_struct6 var)
3992 {
3993         if (var.a.a != 4)
3994                 return 1;
3995         if (var.b != 5)
3996                 return 2;
3997         if (var.c != 6)
3998                 return 3;
3999         return 0;
4000 }
4001
4002 LIBTEST_API int STDCALL  
4003 mono_test_Winx64_structs_in1 (winx64_struct1 var1,
4004                          winx64_struct2 var2,
4005                          winx64_struct3 var3,
4006                          winx64_struct4 var4)
4007 {
4008         if (var1.a != 123)
4009                 return 1;
4010         
4011         if (var2.a != 4)
4012                 return 2;
4013         if (var2.b != 5)
4014                 return 3;
4015         
4016         if (var3.a != 4)
4017                 return 4;
4018         if (var3.b != 5)
4019                 return 2;
4020         if (var3.c != 0x1234)
4021                 return 5;
4022         
4023         if (var4.a != 4)
4024                 return 6;
4025         if (var4.b != 5)
4026                 return 7;
4027         if (var4.c != 0x1234)
4028                 return 8;
4029         if (var4.d != 0x87654321)
4030                 return 9;
4031         return 0;
4032 }
4033
4034 LIBTEST_API int STDCALL  
4035 mono_test_Winx64_structs_in2 (winx64_struct1 var1,
4036                          winx64_struct1 var2,
4037                          winx64_struct1 var3,
4038                          winx64_struct1 var4,
4039                          winx64_struct1 var5)
4040 {
4041         if (var1.a != 1)
4042                 return 1;
4043         if (var2.a != 2)
4044                 return 2;
4045         if (var3.a != 3)
4046                 return 3;
4047         if (var4.a != 4)
4048                 return 4;
4049         if (var5.a != 5)
4050                 return 5;
4051         
4052         return 0;
4053 }
4054
4055 LIBTEST_API int STDCALL  
4056 mono_test_Winx64_structs_in3 (winx64_struct1 var1,
4057                          winx64_struct5 var2,
4058                          winx64_struct1 var3,
4059                          winx64_struct5 var4,
4060                          winx64_struct1 var5,
4061                          winx64_struct5 var6)
4062 {
4063         if (var1.a != 1)
4064                 return 1;
4065         
4066         if (var2.a != 2)
4067                 return 2;
4068         if (var2.b != 3)
4069                 return 2;
4070         if (var2.c != 4)
4071                 return 4;
4072         
4073         if (var3.a != 5)
4074                 return 5;
4075         
4076         if (var4.a != 6)
4077                 return 6;
4078         if (var4.b != 7)
4079                 return 7;
4080         if (var4.c != 8)
4081                 return 8;
4082         
4083         if (var5.a != 9)
4084                 return 9;
4085
4086         if (var6.a != 10)
4087                 return 10;
4088         if (var6.b != 11)
4089                 return 11;
4090         if (var6.c != 12)
4091                 return 12;
4092         
4093         return 0;
4094 }
4095
4096 LIBTEST_API winx64_struct1 STDCALL  
4097 mono_test_Winx64_struct1_ret (void)
4098 {
4099         winx64_struct1 ret;
4100         ret.a = 123;
4101         return ret;
4102 }
4103
4104 LIBTEST_API winx64_struct2 STDCALL  
4105 mono_test_Winx64_struct2_ret (void)
4106 {
4107         winx64_struct2 ret;
4108         ret.a = 4;
4109         ret.b = 5;
4110         return ret;
4111 }
4112
4113 LIBTEST_API winx64_struct3 STDCALL  
4114 mono_test_Winx64_struct3_ret (void)
4115 {
4116         winx64_struct3 ret;
4117         ret.a = 4;
4118         ret.b = 5;
4119         ret.c = 0x1234;
4120         return ret;
4121 }
4122
4123 LIBTEST_API winx64_struct4 STDCALL  
4124 mono_test_Winx64_struct4_ret (void)
4125 {
4126         winx64_struct4 ret;
4127         ret.a = 4;
4128         ret.b = 5;
4129         ret.c = 0x1234;
4130         ret.d = 0x87654321;
4131         return ret;
4132 }
4133
4134 LIBTEST_API winx64_struct5 STDCALL  
4135 mono_test_Winx64_struct5_ret (void)
4136 {
4137         winx64_struct5 ret;
4138         ret.a = 4;
4139         ret.b = 5;
4140         ret.c = 6;
4141         return ret;
4142 }
4143
4144 LIBTEST_API winx64_struct1 STDCALL  
4145 mono_test_Winx64_struct1_ret_5_args (char a, char b, char c, char d, char e)
4146 {
4147         winx64_struct1 ret;
4148         ret.a = a + b + c + d + e;
4149         return ret;
4150 }
4151
4152 LIBTEST_API winx64_struct5 STDCALL
4153 mono_test_Winx64_struct5_ret6_args (char a, char b, char c, char d, char e)
4154 {
4155         winx64_struct5 ret;
4156         ret.a = a + b;
4157         ret.b = c + d;
4158         ret.c = e;
4159         return ret;
4160 }
4161
4162 typedef struct
4163 {
4164         float a;
4165         float b;
4166 } winx64_floatStruct;
4167
4168 LIBTEST_API int STDCALL  
4169 mono_test_Winx64_floatStruct (winx64_floatStruct a)
4170 {
4171         if (a.a > 5.6 || a.a < 5.4)
4172                 return 1;
4173
4174         if (a.b > 9.6 || a.b < 9.4)
4175                 return 2;
4176         
4177         return 0;
4178 }
4179
4180 typedef struct
4181 {
4182         double a;
4183 } winx64_doubleStruct;
4184
4185 LIBTEST_API int STDCALL  
4186 mono_test_Winx64_doubleStruct (winx64_doubleStruct a)
4187 {
4188         if (a.a > 5.6 || a.a < 5.4)
4189                 return 1;
4190         
4191         return 0;
4192 }
4193
4194 typedef int (STDCALL *managed_struct1_delegate) (winx64_struct1 a);
4195
4196 LIBTEST_API int STDCALL 
4197 mono_test_managed_Winx64_struct1_in(managed_struct1_delegate func)
4198 {
4199         winx64_struct1 val;
4200         val.a = 5;
4201         return func (val);
4202 }
4203
4204 typedef int (STDCALL *managed_struct5_delegate) (winx64_struct5 a);
4205
4206 LIBTEST_API int STDCALL 
4207 mono_test_managed_Winx64_struct5_in(managed_struct5_delegate func)
4208 {
4209         winx64_struct5 val;
4210         val.a = 5;
4211         val.b = 0x10;
4212         val.c = 0x99;
4213         return func (val);
4214 }
4215
4216 typedef int (STDCALL *managed_struct1_struct5_delegate) (winx64_struct1 a, winx64_struct5 b,
4217                                                          winx64_struct1 c, winx64_struct5 d,
4218                                                          winx64_struct1 e, winx64_struct5 f);
4219
4220 LIBTEST_API int STDCALL 
4221 mono_test_managed_Winx64_struct1_struct5_in(managed_struct1_struct5_delegate func)
4222 {
4223         winx64_struct1 a, c, e;
4224         winx64_struct5 b, d, f;
4225         a.a = 1;
4226         b.a = 2; b.b = 3; b.c = 4;
4227         c.a = 5;
4228         d.a = 6; d.b = 7; d.c = 8;
4229         e.a = 9;
4230         f.a = 10; f.b = 11; f.c = 12;
4231
4232         return func (a, b, c, d, e, f);
4233 }
4234
4235 typedef winx64_struct1 (STDCALL *managed_struct1_ret_delegate) (void);
4236
4237 LIBTEST_API int STDCALL 
4238 mono_test_Winx64_struct1_ret_managed (managed_struct1_ret_delegate func)
4239 {
4240         winx64_struct1 ret;
4241
4242         ret = func ();
4243
4244         if (ret.a != 0x45)
4245                 return 1;
4246         
4247         return 0;
4248 }
4249
4250 typedef winx64_struct5 (STDCALL *managed_struct5_ret_delegate) (void);
4251
4252 LIBTEST_API int STDCALL 
4253 mono_test_Winx64_struct5_ret_managed (managed_struct5_ret_delegate func)
4254 {
4255         winx64_struct5 ret;
4256
4257         ret = func ();
4258
4259         if (ret.a != 0x12)
4260                 return 1;
4261         if (ret.b != 0x34)
4262                 return 2;
4263         if (ret.c != 0x56)
4264                 return 3;
4265         
4266         return 0;
4267 }
4268
4269 LIBTEST_API int STDCALL 
4270 mono_test_marshal_bool_in (int arg, unsigned int expected, unsigned int bDefaultMarsh, unsigned int bBoolCustMarsh,
4271                            char bI1CustMarsh, unsigned char bU1CustMarsh, short bVBCustMarsh)
4272 {
4273         switch (arg) {
4274         case 1: 
4275                 if (bDefaultMarsh != expected)
4276                         return 1;
4277                 break;
4278         case 2: 
4279                 if (bBoolCustMarsh != expected)
4280                         return 2;
4281                 break;
4282         case 3: 
4283                 if (bI1CustMarsh != expected)
4284                         return 3;
4285                 break;
4286         case 4: 
4287                 if (bU1CustMarsh != expected)
4288                         return 4;
4289                 break;
4290         case 5: 
4291                 if (bVBCustMarsh != expected)
4292                         return 5;
4293                 break;
4294         default:
4295                 return 999;             
4296         }
4297         return 0;
4298 }
4299
4300 LIBTEST_API int STDCALL 
4301 mono_test_marshal_bool_out (int arg, unsigned int testVal, unsigned int* bDefaultMarsh, unsigned int* bBoolCustMarsh,
4302                            char* bI1CustMarsh, unsigned char* bU1CustMarsh, unsigned short* bVBCustMarsh)
4303 {
4304         switch (arg) {
4305         case 1: 
4306                 if (!bDefaultMarsh)
4307                         return 1;
4308                 *bDefaultMarsh = testVal;
4309                 break;  
4310         case 2: 
4311                 if (!bBoolCustMarsh)
4312                         return 2;
4313                 *bBoolCustMarsh = testVal;
4314                 break;  
4315         case 3: 
4316                 if (!bI1CustMarsh)
4317                         return 3;
4318                 *bI1CustMarsh = (char)testVal;
4319                 break;  
4320         case 4: 
4321                 if (!bU1CustMarsh)
4322                         return 4;
4323                 *bU1CustMarsh = (unsigned char)testVal;
4324                 break;  
4325         case 5: 
4326                 if (!bVBCustMarsh)
4327                         return 5;
4328                 *bVBCustMarsh = (unsigned short)testVal;
4329                 break;  
4330         default:
4331                 return 999;
4332         }
4333         return 0;
4334 }
4335
4336 LIBTEST_API int STDCALL 
4337 mono_test_marshal_bool_ref (int arg, unsigned int expected, unsigned int testVal, unsigned int* bDefaultMarsh,
4338                             unsigned int* bBoolCustMarsh, char* bI1CustMarsh, unsigned char* bU1CustMarsh, 
4339                             unsigned short* bVBCustMarsh)
4340 {
4341         switch (arg) {
4342         case 1: 
4343                 if (!bDefaultMarsh)
4344                         return 1;
4345                 if (*bDefaultMarsh != expected)
4346                         return 2;
4347                 *bDefaultMarsh = testVal;
4348                 break;
4349         case 2: 
4350                 if (!bBoolCustMarsh)
4351                         return 3;
4352                 if (*bBoolCustMarsh != expected)
4353                         return 4;
4354                 *bBoolCustMarsh = testVal;
4355                 break;
4356         case 3: 
4357                 if (!bI1CustMarsh)
4358                         return 5;
4359                 if (*bI1CustMarsh != expected)
4360                         return 6;
4361                 *bI1CustMarsh = (char)testVal;
4362                 break;
4363         case 4: 
4364                 if (!bU1CustMarsh)
4365                         return 7;
4366                 if (*bU1CustMarsh != expected)
4367                         return 8;
4368                 *bU1CustMarsh = (unsigned char)testVal;
4369                 break;
4370         case 5: 
4371                 if (!bVBCustMarsh)
4372                         return 9;
4373                 if (*bVBCustMarsh != expected)
4374                         return 10;
4375                 *bVBCustMarsh = (unsigned short)testVal;
4376                 break;
4377         default:
4378                 return 999;             
4379         }
4380         return 0;
4381 }
4382
4383
4384 typedef int (STDCALL *MarshalBoolInDelegate) (int arg, unsigned int expected, unsigned int bDefaultMarsh,
4385         unsigned int bBoolCustMarsh, char bI1CustMarsh, unsigned char bU1CustMarsh, unsigned short bVBCustMarsh);
4386
4387 LIBTEST_API int STDCALL 
4388 mono_test_managed_marshal_bool_in (int arg, unsigned int expected, unsigned int testVal, MarshalBoolInDelegate pfcn)
4389 {
4390         if (!pfcn)
4391                 return 0x9900;
4392
4393         switch (arg) {
4394         case 1:
4395                 return pfcn (arg, expected, testVal, 0, 0, 0, 0);
4396         case 2:
4397                 return pfcn (arg, expected, 0, testVal,  0, 0, 0);
4398         case 3:
4399                 return pfcn (arg, expected, 0, 0, testVal, 0, 0);
4400         case 4:
4401                 return pfcn (arg, expected, 0, 0, 0, testVal, 0);
4402         case 5:
4403                 return pfcn (arg, expected, 0, 0, 0, 0, testVal);
4404         default:
4405                 return 0x9800;
4406         }
4407
4408         return 0;
4409 }
4410
4411 typedef int (STDCALL *MarshalBoolOutDelegate) (int arg, unsigned int expected, unsigned int* bDefaultMarsh,
4412         unsigned int* bBoolCustMarsh, char* bI1CustMarsh, unsigned char* bU1CustMarsh, unsigned short* bVBCustMarsh);
4413
4414 LIBTEST_API int STDCALL 
4415 mono_test_managed_marshal_bool_out (int arg, unsigned int expected, unsigned int testVal, MarshalBoolOutDelegate pfcn)
4416 {
4417         int ret;
4418         unsigned int lDefaultMarsh, lBoolCustMarsh;
4419         char lI1CustMarsh = 0;
4420         unsigned char lU1CustMarsh = 0;
4421         unsigned short lVBCustMarsh = 0;
4422         lDefaultMarsh = lBoolCustMarsh = 0;
4423
4424         if (!pfcn)
4425                 return 0x9900;
4426
4427         switch (arg) {
4428         case 1: {
4429                 unsigned int ltVal = 0;
4430                 ret = pfcn (arg, testVal, &ltVal, &lBoolCustMarsh, &lI1CustMarsh, &lU1CustMarsh, &lVBCustMarsh);
4431                 if (ret)
4432                         return 0x0100 + ret;
4433                 if (expected != ltVal)
4434                         return 0x0200;
4435                 break;
4436         }
4437         case 2: {
4438                 unsigned int ltVal = 0;
4439                 ret = pfcn (arg, testVal, &lDefaultMarsh, &ltVal, &lI1CustMarsh, &lU1CustMarsh, &lVBCustMarsh);
4440                 if (ret)
4441                         return 0x0300 + ret;
4442                 if (expected != ltVal)
4443                         return 0x0400;
4444                 break;
4445         }
4446         case 3: {
4447                 char ltVal = 0;
4448                 ret = pfcn (arg, testVal, &lDefaultMarsh, &lBoolCustMarsh, &ltVal, &lU1CustMarsh, &lVBCustMarsh);
4449                 if (ret)
4450                         return 0x0500 + ret;
4451                 if (expected != ltVal)
4452                         return 0x0600;
4453                 break;
4454         }
4455         case 4: {
4456                 unsigned char ltVal = 0;
4457                 ret = pfcn (arg, testVal, &lDefaultMarsh, &lBoolCustMarsh, &lI1CustMarsh, &ltVal, &lVBCustMarsh);
4458                 if (ret)
4459                         return 0x0700 + ret;
4460                 if (expected != ltVal)
4461                         return 0x0800;
4462                 break;
4463         }
4464         case 5: {
4465                 unsigned short ltVal = 0;
4466                 ret = pfcn (arg, testVal, &lDefaultMarsh, &lBoolCustMarsh, &lI1CustMarsh, &lU1CustMarsh, &ltVal);
4467                 if (ret)
4468                         return 0x0900 + ret;
4469                 if (expected != ltVal)
4470                         return 0x1000;
4471                 break;
4472         }
4473         default:
4474                 return 0x9800;
4475         }
4476
4477         return 0;
4478 }
4479
4480 typedef int (STDCALL *MarshalBoolRefDelegate) (int arg, unsigned int expected, unsigned int testVal, unsigned int* bDefaultMarsh,
4481         unsigned int* bBoolCustMarsh, char* bI1CustMarsh, unsigned char* bU1CustMarsh, unsigned short* bVBCustMarsh);
4482
4483 LIBTEST_API int STDCALL 
4484 mono_test_managed_marshal_bool_ref (int arg, unsigned int expected, unsigned int testVal, unsigned int outExpected,
4485                                     unsigned int outTestVal, MarshalBoolRefDelegate pfcn)
4486 {
4487         int ret;
4488         unsigned int lDefaultMarsh, lBoolCustMarsh;
4489         char lI1CustMarsh = 0;
4490         unsigned char lU1CustMarsh = 0;
4491         unsigned short lVBCustMarsh = 0;
4492         lDefaultMarsh = lBoolCustMarsh = 0;
4493
4494         if (!pfcn)
4495                 return 0x9900;
4496
4497         switch (arg) {
4498         case 1:
4499         {
4500                 unsigned int ltestVal = testVal;
4501                 ret = pfcn (arg, expected, outTestVal, &ltestVal, &lBoolCustMarsh, &lI1CustMarsh, &lU1CustMarsh, &lVBCustMarsh);
4502                 if (ret)
4503                         return 0x0100 + ret;
4504                 if (outExpected != ltestVal)
4505                         return 0x0200;
4506                 break;
4507         }
4508         case 2:
4509         {
4510                 unsigned int ltestVal = testVal;
4511                 ret = pfcn (arg, expected, outTestVal, &lDefaultMarsh, &ltestVal, &lI1CustMarsh, &lU1CustMarsh, &lVBCustMarsh);
4512                 if (ret)
4513                         return 0x0300 + ret;
4514                 if (outExpected != ltestVal)
4515                         return 0x0400;
4516                 break;
4517         }
4518         case 3:
4519         {
4520                 char ltestVal = testVal;
4521                 ret = pfcn (arg, expected, outTestVal, &lDefaultMarsh, &lBoolCustMarsh, &ltestVal, &lU1CustMarsh, &lVBCustMarsh);
4522                 if (ret)
4523                         return 0x0500 + ret;
4524                 if (outExpected != ltestVal)
4525                         return 0x0600;
4526                 break;
4527         }
4528         case 4:
4529         {
4530                 unsigned char ltestVal = testVal;
4531                 ret = pfcn (arg, expected, outTestVal, &lDefaultMarsh, &lBoolCustMarsh, &lI1CustMarsh, &ltestVal, &lVBCustMarsh);
4532                 if (ret)
4533                         return 0x0700 + ret;
4534                 if (outExpected != ltestVal)
4535                         return 0x0800;
4536                 break;
4537         }
4538         case 5:
4539         {
4540                 unsigned short ltestVal = testVal;
4541                 ret = pfcn (arg, expected, outTestVal, &lDefaultMarsh, &lBoolCustMarsh, &lI1CustMarsh, &lU1CustMarsh, &ltestVal);
4542                 if (ret)
4543                         return 0x0900 + ret;
4544                 if (outExpected != ltestVal)
4545                         return 0x1000;
4546                 break;
4547         }
4548         default:
4549                 return 0x9800;
4550         }
4551
4552         return 0;
4553 }
4554
4555 #ifdef WIN32
4556
4557 LIBTEST_API int STDCALL 
4558 mono_test_marshal_safearray_out_1dim_vt_bstr_empty (SAFEARRAY** safearray)
4559 {
4560         /* Create an empty one-dimensional array of variants */
4561         SAFEARRAY *pSA;
4562         SAFEARRAYBOUND dimensions [1];
4563
4564         dimensions [0].lLbound = 0;
4565         dimensions [0].cElements = 0;
4566
4567         pSA= SafeArrayCreate (VT_VARIANT, 1, dimensions);
4568         *safearray = pSA;
4569         return S_OK;
4570 }
4571
4572 LIBTEST_API int STDCALL 
4573 mono_test_marshal_safearray_out_1dim_vt_bstr (SAFEARRAY** safearray)
4574 {
4575         /* Create a one-dimensional array of 10 variants filled with "0" to "9" */
4576         SAFEARRAY *pSA;
4577         SAFEARRAYBOUND dimensions [1];
4578         long i;
4579         gchar buffer [20];
4580         HRESULT hr = S_OK;
4581         long indices [1];
4582
4583         dimensions [0].lLbound = 0;
4584         dimensions [0].cElements = 10;
4585
4586         pSA= SafeArrayCreate (VT_VARIANT, 1, dimensions);
4587         for (i= dimensions [0].lLbound; i< (dimensions [0].cElements + dimensions [0].lLbound); i++) {
4588                 VARIANT vOut;
4589                 VariantInit (&vOut);
4590                 vOut.vt = VT_BSTR;
4591                 _ltoa (i,buffer,10);
4592                 vOut.bstrVal= marshal_bstr_alloc (buffer);
4593                 indices [0] = i;
4594                 if ((hr = SafeArrayPutElement (pSA, indices, &vOut)) != S_OK) {
4595                         VariantClear (&vOut);
4596                         SafeArrayDestroy (pSA);
4597                         return hr;
4598                 }
4599                 VariantClear (&vOut);
4600         }
4601         *safearray = pSA;
4602         return hr;
4603 }
4604
4605 LIBTEST_API int STDCALL 
4606 mono_test_marshal_safearray_out_2dim_vt_i4 (SAFEARRAY** safearray)
4607 {
4608         /* Create a two-dimensional array of 4x3 variants filled with 11, 12, 13, etc. */
4609         SAFEARRAY *pSA;
4610         SAFEARRAYBOUND dimensions [2];
4611         long i, j;
4612         HRESULT hr = S_OK;
4613         long indices [2];
4614
4615         dimensions [0].lLbound = 0;
4616         dimensions [0].cElements = 4;
4617         dimensions [1].lLbound = 0;
4618         dimensions [1].cElements = 3;
4619
4620         pSA= SafeArrayCreate(VT_VARIANT, 2, dimensions);
4621         for (i= dimensions [0].lLbound; i< (dimensions [0].cElements + dimensions [0].lLbound); i++) {
4622                 for (j= dimensions [1].lLbound; j< (dimensions [1].cElements + dimensions [1].lLbound); j++) {
4623                         VARIANT vOut;
4624                         VariantInit (&vOut);
4625                         vOut.vt = VT_I4;
4626                         vOut.lVal = (i+1)*10+(j+1);
4627                         indices [0] = i;
4628                         indices [1] = j;
4629                         if ((hr = SafeArrayPutElement (pSA, indices, &vOut)) != S_OK) {
4630                                 VariantClear (&vOut);
4631                                 SafeArrayDestroy (pSA);
4632                                 return hr;
4633                         }
4634                         VariantClear (&vOut);  // does a deep destroy of source VARIANT 
4635                 }
4636         }
4637         *safearray = pSA;
4638         return hr;
4639 }
4640
4641 LIBTEST_API int STDCALL 
4642 mono_test_marshal_safearray_out_4dim_vt_i4 (SAFEARRAY** safearray)
4643 {
4644         /* Create a four-dimensional array of 10x3x6x7 variants filled with their indices */
4645         /* Also use non zero lower bounds                                                 */
4646         SAFEARRAY *pSA;
4647         SAFEARRAYBOUND dimensions [4];
4648         long i;
4649         HRESULT hr = S_OK;
4650         VARIANT *pData;
4651
4652         dimensions [0].lLbound = 15;
4653         dimensions [0].cElements = 10;
4654         dimensions [1].lLbound = 20;
4655         dimensions [1].cElements = 3;
4656         dimensions [2].lLbound = 5;
4657         dimensions [2].cElements = 6;
4658         dimensions [3].lLbound = 12;
4659         dimensions [3].cElements = 7;
4660
4661         pSA= SafeArrayCreate (VT_VARIANT, 4, dimensions);
4662
4663         SafeArrayAccessData (pSA, (void **)&pData);
4664
4665         for (i= 0; i< 10*3*6*7; i++) {
4666                 VariantInit(&pData [i]);
4667                 pData [i].vt = VT_I4;
4668                 pData [i].lVal = i;
4669         }
4670         SafeArrayUnaccessData (pSA);
4671         *safearray = pSA;
4672         return hr;
4673 }
4674
4675 LIBTEST_API int STDCALL 
4676 mono_test_marshal_safearray_in_byval_1dim_empty (SAFEARRAY* safearray)
4677 {
4678         /* Check that array is one dimensional and empty */
4679
4680         UINT dim;
4681         long lbound, ubound;
4682         
4683         dim = SafeArrayGetDim (safearray);
4684         if (dim != 1)
4685                 return 1;
4686
4687         SafeArrayGetLBound (safearray, 1, &lbound);
4688         SafeArrayGetUBound (safearray, 1, &ubound);
4689
4690         if ((lbound > 0) || (ubound > 0))
4691                 return 1;
4692
4693         return 0;
4694 }
4695
4696 LIBTEST_API int STDCALL 
4697 mono_test_marshal_safearray_in_byval_1dim_vt_i4 (SAFEARRAY* safearray)
4698 {
4699         /* Check that array is one dimensional containing integers from 1 to 10 */
4700
4701         UINT dim;
4702         long lbound, ubound;
4703         VARIANT *pData; 
4704         long i;
4705         int result=0;
4706
4707         dim = SafeArrayGetDim (safearray);
4708         if (dim != 1)
4709                 return 1;
4710
4711         SafeArrayGetLBound (safearray, 1, &lbound);
4712         SafeArrayGetUBound (safearray, 1, &ubound);
4713
4714         if ((lbound != 0) || (ubound != 9))
4715                 return 1;
4716
4717         SafeArrayAccessData (safearray, (void **)&pData);
4718         for (i= lbound; i <= ubound; i++) {
4719                 if ((VariantChangeType (&pData [i], &pData [i], VARIANT_NOUSEROVERRIDE, VT_I4) != S_OK) || (pData [i].lVal != i + 1))
4720                         result = 1;
4721         }
4722         SafeArrayUnaccessData (safearray);
4723
4724         return result;
4725 }
4726
4727 LIBTEST_API int STDCALL 
4728 mono_test_marshal_safearray_in_byval_1dim_vt_mixed (SAFEARRAY* safearray)
4729 {
4730         /* Check that array is one dimensional containing integers mixed with strings from 0 to 12 */
4731
4732         UINT dim;
4733         long lbound, ubound;
4734         VARIANT *pData; 
4735         long i;
4736         long indices [1];
4737         VARIANT element;
4738         int result=0;
4739
4740         VariantInit (&element);
4741
4742         dim = SafeArrayGetDim (safearray);
4743         if (dim != 1)
4744                 return 1;
4745
4746         SafeArrayGetLBound (safearray, 1, &lbound);
4747         SafeArrayGetUBound (safearray, 1, &ubound);
4748                 
4749         if ((lbound != 0) || (ubound != 12))
4750                 return 1;
4751
4752         SafeArrayAccessData (safearray, (void **)&pData);
4753         for (i= lbound; i <= ubound; i++) {
4754                 if ((i%2 == 0) && (pData [i].vt != VT_I4))
4755                         result = 1;
4756                 if ((i%2 == 1) && (pData [i].vt != VT_BSTR))
4757                         result = 1;
4758                 if ((VariantChangeType (&pData [i], &pData [i], VARIANT_NOUSEROVERRIDE, VT_I4) != S_OK) || (pData [i].lVal != i))
4759                         result = 1;
4760         }
4761         SafeArrayUnaccessData (safearray);
4762
4763         /* Change the first element of the array to verify that [in] parameters are not marshalled back to the managed side */
4764
4765         indices [0] = 0;
4766         element.vt = VT_I4;
4767         element.lVal = 333;
4768         SafeArrayPutElement (safearray, indices, &element);
4769         VariantClear (&element);
4770
4771         return result;
4772 }
4773
4774 LIBTEST_API int STDCALL 
4775 mono_test_marshal_safearray_in_byval_2dim_vt_i4 (SAFEARRAY* safearray)
4776 {
4777         /* Check that array is one dimensional containing integers mixed with strings from 0 to 12 */
4778
4779         UINT dim;
4780         long lbound1, ubound1, lbound2, ubound2;
4781         long i, j, failed;
4782         long indices [2];
4783         VARIANT element;
4784
4785         VariantInit (&element);
4786
4787         dim = SafeArrayGetDim (safearray);
4788         if (dim != 2)
4789                 return 1;
4790
4791         SafeArrayGetLBound (safearray, 1, &lbound1);
4792         SafeArrayGetUBound (safearray, 1, &ubound1);
4793
4794         if ((lbound1 != 0) || (ubound1 != 1))
4795                 return 1;
4796
4797         SafeArrayGetLBound (safearray, 2, &lbound2);
4798         SafeArrayGetUBound (safearray, 2, &ubound2);
4799
4800         if ((lbound2 != 0) || (ubound2 != 3)) {
4801                 return 1;
4802         }
4803
4804         for (i= lbound1; i <= ubound1; i++) {
4805                 indices [0] = i;
4806                 for (j= lbound2; j <= ubound2; j++) {
4807                         indices [1] = j;
4808                         if (SafeArrayGetElement (safearray, indices, &element) != S_OK)
4809                                 return 1;
4810                         failed = ((element.vt != VT_I4) || (element.lVal != 10*(i+1)+(j+1)));
4811                         VariantClear (&element);
4812                         if (failed)
4813                                 return 1;
4814                 }
4815         }
4816
4817         /* Change the first element of the array to verify that [in] parameters are not marshalled back to the managed side */
4818
4819         indices [0] = 0;
4820         indices [1] = 0;
4821         element.vt = VT_I4;
4822         element.lVal = 333;
4823         SafeArrayPutElement (safearray, indices, &element);
4824         VariantClear (&element);
4825
4826         return 0;
4827 }
4828
4829 LIBTEST_API int STDCALL 
4830 mono_test_marshal_safearray_in_byval_3dim_vt_bstr (SAFEARRAY* safearray)
4831 {
4832         /* Check that array is one dimensional containing integers mixed with strings from 0 to 12 */
4833
4834         UINT dim;
4835         long lbound1, ubound1, lbound2, ubound2, lbound3, ubound3;
4836         long i, j, k, failed;
4837         long indices [3];
4838         VARIANT element;
4839
4840         VariantInit (&element);
4841
4842         dim = SafeArrayGetDim (safearray);
4843         if (dim != 3)
4844                 return 1;
4845
4846         SafeArrayGetLBound (safearray, 1, &lbound1);
4847         SafeArrayGetUBound (safearray, 1, &ubound1);
4848
4849         if ((lbound1 != 0) || (ubound1 != 1))
4850                 return 1;
4851
4852         SafeArrayGetLBound (safearray, 2, &lbound2);
4853         SafeArrayGetUBound (safearray, 2, &ubound2);
4854
4855         if ((lbound2 != 0) || (ubound2 != 1))
4856                 return 1;
4857
4858         SafeArrayGetLBound (safearray, 3, &lbound3);
4859         SafeArrayGetUBound (safearray, 3, &ubound3);
4860
4861         if ((lbound3 != 0) || (ubound3 != 2))
4862                 return 1;
4863
4864         for (i= lbound1; i <= ubound1; i++) {
4865                 indices [0] = i;
4866                 for (j= lbound2; j <= ubound2; j++) {
4867                         indices [1] = j;
4868                 for (k= lbound3; k <= ubound3; k++) {
4869                                 indices [2] = k;
4870                                 if (SafeArrayGetElement (safearray, indices, &element) != S_OK)
4871                                         return 1;
4872                                 failed = ((element.vt != VT_BSTR) 
4873                                         || (VariantChangeType (&element, &element, VARIANT_NOUSEROVERRIDE, VT_I4) != S_OK) 
4874                                         || (element.lVal != 100*(i+1)+10*(j+1)+(k+1)));
4875                                 VariantClear (&element);
4876                                 if (failed)
4877                                         return 1;
4878                         }
4879                 }
4880         }
4881
4882         /* Change the first element of the array to verify that [in] parameters are not marshalled back to the managed side */
4883
4884         indices [0] = 0;
4885         indices [1] = 0;
4886         indices [2] = 0;
4887         element.vt = VT_BSTR;
4888         element.bstrVal = SysAllocString(L"Should not be copied");
4889         SafeArrayPutElement (safearray, indices, &element);
4890         VariantClear (&element);
4891
4892         return 0;
4893 }
4894
4895 LIBTEST_API int STDCALL 
4896 mono_test_marshal_safearray_in_byref_3dim_vt_bstr (SAFEARRAY** safearray)
4897 {
4898         return mono_test_marshal_safearray_in_byval_3dim_vt_bstr (*safearray);
4899 }
4900
4901 LIBTEST_API int STDCALL 
4902 mono_test_marshal_safearray_in_out_byref_1dim_empty (SAFEARRAY** safearray)
4903 {
4904         /* Check that the input array is what is expected and change it so the caller can check */
4905         /* correct marshalling back to managed code                                             */
4906
4907         UINT dim;
4908         long lbound, ubound;
4909         SAFEARRAYBOUND dimensions [1];
4910         long i;
4911         wchar_t buffer [20];
4912         HRESULT hr = S_OK;
4913         long indices [1];
4914
4915         /* Check that in array is one dimensional and empty */
4916
4917         dim = SafeArrayGetDim (*safearray);
4918         if (dim != 1) {
4919                 return 1;
4920         }
4921
4922         SafeArrayGetLBound (*safearray, 1, &lbound);
4923         SafeArrayGetUBound (*safearray, 1, &ubound);
4924                 
4925         if ((lbound > 0) || (ubound > 0)) {
4926                 return 1;
4927         }
4928
4929         /* Re-dimension the array and return a one-dimensional array of 8 variants filled with "0" to "7" */
4930
4931         dimensions [0].lLbound = 0;
4932         dimensions [0].cElements = 8;
4933
4934         hr = SafeArrayRedim (*safearray, dimensions);
4935         if (hr != S_OK)
4936                 return 1;
4937
4938         for (i= dimensions [0].lLbound; i< (dimensions [0].lLbound + dimensions [0].cElements); i++) {
4939                 VARIANT vOut;
4940                 VariantInit (&vOut);
4941                 vOut.vt = VT_BSTR;
4942                 _ltow (i,buffer,10);
4943                 vOut.bstrVal = SysAllocString (buffer);
4944                 indices [0] = i;
4945                 if ((hr = SafeArrayPutElement (*safearray, indices, &vOut)) != S_OK) {
4946                         VariantClear (&vOut);
4947                         SafeArrayDestroy (*safearray);
4948                         return hr;
4949                 }
4950                 VariantClear (&vOut);
4951         }
4952         return hr;
4953 }
4954
4955 LIBTEST_API int STDCALL 
4956 mono_test_marshal_safearray_in_out_byref_3dim_vt_bstr (SAFEARRAY** safearray)
4957 {
4958         /* Check that the input array is what is expected and change it so the caller can check */
4959         /* correct marshalling back to managed code                                             */
4960
4961         UINT dim;
4962         long lbound1, ubound1, lbound2, ubound2, lbound3, ubound3;
4963         SAFEARRAYBOUND dimensions [1];
4964         long i, j, k, failed;
4965         wchar_t buffer [20];
4966         HRESULT hr = S_OK;
4967         long indices [3];
4968         VARIANT element;
4969
4970         VariantInit (&element);
4971
4972         /* Check that in array is three dimensional and contains the expected values */
4973
4974         dim = SafeArrayGetDim (*safearray);
4975         if (dim != 3)
4976                 return 1;
4977
4978         SafeArrayGetLBound (*safearray, 1, &lbound1);
4979         SafeArrayGetUBound (*safearray, 1, &ubound1);
4980
4981         if ((lbound1 != 0) || (ubound1 != 1))
4982                 return 1;
4983
4984         SafeArrayGetLBound (*safearray, 2, &lbound2);
4985         SafeArrayGetUBound (*safearray, 2, &ubound2);
4986
4987         if ((lbound2 != 0) || (ubound2 != 1))
4988                 return 1;
4989
4990         SafeArrayGetLBound (*safearray, 3, &lbound3);
4991         SafeArrayGetUBound (*safearray, 3, &ubound3);
4992
4993         if ((lbound3 != 0) || (ubound3 != 2))
4994                 return 1;
4995
4996         for (i= lbound1; i <= ubound1; i++) {
4997                 indices [0] = i;
4998                 for (j= lbound2; j <= ubound2; j++) {
4999                         indices [1] = j;
5000                         for (k= lbound3; k <= ubound3; k++) {
5001                                 indices [2] = k;
5002                                 if (SafeArrayGetElement (*safearray, indices, &element) != S_OK)
5003                                         return 1;
5004                                 failed = ((element.vt != VT_BSTR) 
5005                                         || (VariantChangeType (&element, &element, VARIANT_NOUSEROVERRIDE, VT_I4) != S_OK) 
5006                                         || (element.lVal != 100*(i+1)+10*(j+1)+(k+1)));
5007                                 VariantClear (&element);
5008                                 if (failed)
5009                                         return 1;
5010                         }
5011                 }
5012         }
5013
5014         hr = SafeArrayDestroy (*safearray);
5015         if (hr != S_OK)
5016                 return 1;
5017
5018         /* Return a new one-dimensional array of 8 variants filled with "0" to "7" */
5019
5020         dimensions [0].lLbound = 0;
5021         dimensions [0].cElements = 8;
5022
5023         *safearray = SafeArrayCreate (VT_VARIANT, 1, dimensions);
5024
5025         for (i= dimensions [0].lLbound; i< (dimensions [0].lLbound + dimensions [0].cElements); i++) {
5026                 VARIANT vOut;
5027                 VariantInit (&vOut);
5028                 vOut.vt = VT_BSTR;
5029                 _ltow (i,buffer,10);
5030                 vOut.bstrVal = SysAllocString (buffer);
5031                 indices [0] = i;
5032                 if ((hr = SafeArrayPutElement (*safearray, indices, &vOut)) != S_OK) {
5033                         VariantClear (&vOut);
5034                         SafeArrayDestroy (*safearray);
5035                         return hr;
5036                 }
5037                 VariantClear (&vOut);
5038         }
5039         return hr;
5040 }
5041
5042 LIBTEST_API int STDCALL 
5043 mono_test_marshal_safearray_in_out_byref_1dim_vt_i4 (SAFEARRAY** safearray)
5044 {
5045         /* Check that the input array is what is expected and change it so the caller can check */
5046         /* correct marshalling back to managed code                                             */
5047
5048         UINT dim;
5049         long lbound1, ubound1;
5050         long i, failed;
5051         HRESULT hr = S_OK;
5052         long indices [1];
5053         VARIANT element;
5054         
5055         VariantInit (&element);
5056
5057         /* Check that in array is one dimensional and contains the expected value */
5058
5059         dim = SafeArrayGetDim (*safearray);
5060         if (dim != 1)
5061                 return 1;
5062
5063         SafeArrayGetLBound (*safearray, 1, &lbound1);
5064         SafeArrayGetUBound (*safearray, 1, &ubound1);
5065
5066         ubound1 = 1;
5067         if ((lbound1 != 0) || (ubound1 != 1))
5068                 return 1;
5069         ubound1 = 0;
5070
5071         for (i= lbound1; i <= ubound1; i++) {
5072                 indices [0] = i;
5073                 if (SafeArrayGetElement (*safearray, indices, &element) != S_OK)
5074                         return 1;
5075                 failed = (element.vt != VT_I4) || (element.lVal != i+1);
5076                 VariantClear (&element);
5077                 if (failed)
5078                         return 1;
5079         }
5080
5081         /* Change one of the elements of the array to verify that [out] parameter is marshalled back to the managed side */
5082
5083         indices [0] = 0;
5084         element.vt = VT_I4;
5085         element.lVal = -1;
5086         SafeArrayPutElement (*safearray, indices, &element);
5087         VariantClear (&element);
5088
5089         return hr;
5090 }
5091
5092 LIBTEST_API int STDCALL 
5093 mono_test_marshal_safearray_in_out_byval_1dim_vt_i4 (SAFEARRAY* safearray)
5094 {
5095         /* Check that the input array is what is expected and change it so the caller can check */
5096         /* correct marshalling back to managed code                                             */
5097
5098         UINT dim;
5099         long lbound1, ubound1;
5100         SAFEARRAYBOUND dimensions [1];
5101         long i, failed;
5102         HRESULT hr = S_OK;
5103         long indices [1];
5104         VARIANT element;
5105
5106         VariantInit (&element);
5107
5108         /* Check that in array is one dimensional and contains the expected value */
5109
5110         dim = SafeArrayGetDim (safearray);
5111         if (dim != 1)
5112                 return 1;
5113
5114         SafeArrayGetLBound (safearray, 1, &lbound1);
5115         SafeArrayGetUBound (safearray, 1, &ubound1);
5116                 
5117         if ((lbound1 != 0) || (ubound1 != 0))
5118                 return 1;
5119
5120         for (i= lbound1; i <= ubound1; i++) {
5121                 indices [0] = i;
5122                 if (SafeArrayGetElement (safearray, indices, &element) != S_OK)
5123                         return 1;
5124                 failed = (element.vt != VT_I4) || (element.lVal != i+1);
5125                 VariantClear (&element);
5126                 if (failed)
5127                         return 1;
5128         }
5129
5130         /* Change the array to verify how [out] parameter is marshalled back to the managed side */
5131
5132         /* Redimension the array */
5133         dimensions [0].lLbound = lbound1;
5134         dimensions [0].cElements = 2;
5135         hr = SafeArrayRedim(safearray, dimensions);
5136
5137         indices [0] = 0;
5138         element.vt = VT_I4;
5139         element.lVal = 12345;
5140         SafeArrayPutElement (safearray, indices, &element);
5141         VariantClear (&element);
5142
5143         indices [0] = 1;
5144         element.vt = VT_I4;
5145         element.lVal = -12345;
5146         SafeArrayPutElement (safearray, indices, &element);
5147         VariantClear (&element);
5148
5149         return hr;
5150 }
5151
5152 LIBTEST_API int STDCALL 
5153 mono_test_marshal_safearray_in_out_byval_3dim_vt_bstr (SAFEARRAY* safearray)
5154 {
5155         /* Check that the input array is what is expected and change it so the caller can check */
5156         /* correct marshalling back to managed code                                             */
5157
5158         UINT dim;
5159         long lbound1, ubound1, lbound2, ubound2, lbound3, ubound3;
5160         long i, j, k, failed;
5161         HRESULT hr = S_OK;
5162         long indices [3];
5163         VARIANT element;
5164
5165         VariantInit (&element);
5166
5167         /* Check that in array is three dimensional and contains the expected values */
5168
5169         dim = SafeArrayGetDim (safearray);
5170         if (dim != 3)
5171                 return 1;
5172
5173         SafeArrayGetLBound (safearray, 1, &lbound1);
5174         SafeArrayGetUBound (safearray, 1, &ubound1);
5175
5176         if ((lbound1 != 0) || (ubound1 != 1))
5177                 return 1;
5178
5179         SafeArrayGetLBound (safearray, 2, &lbound2);
5180         SafeArrayGetUBound (safearray, 2, &ubound2);
5181
5182         if ((lbound2 != 0) || (ubound2 != 1))
5183                 return 1;
5184
5185         SafeArrayGetLBound (safearray, 3, &lbound3);
5186         SafeArrayGetUBound (safearray, 3, &ubound3);
5187
5188         if ((lbound3 != 0) || (ubound3 != 2))
5189                 return 1;
5190
5191         for (i= lbound1; i <= ubound1; i++) {
5192                 indices [0] = i;
5193                 for (j= lbound2; j <= ubound2; j++) {
5194                         indices [1] = j;
5195                         for (k= lbound3; k <= ubound3; k++) {
5196                                 indices [2] = k;
5197                                 if (SafeArrayGetElement (safearray, indices, &element) != S_OK)
5198                                         return 1;
5199                                 failed = ((element.vt != VT_BSTR) 
5200                                         || (VariantChangeType (&element, &element, VARIANT_NOUSEROVERRIDE, VT_I4) != S_OK) 
5201                                         || (element.lVal != 100*(i+1)+10*(j+1)+(k+1)));
5202                                 VariantClear (&element);
5203                                 if (failed)
5204                                         return 1;
5205                         }
5206                 }
5207         }
5208
5209         /* Change the elements of the array to verify that [out] parameter is marshalled back to the managed side */
5210
5211         indices [0] = 1;
5212         indices [1] = 1;
5213         indices [2] = 2;
5214         element.vt = VT_I4;
5215         element.lVal = 333;
5216         SafeArrayPutElement (safearray, indices, &element);
5217         VariantClear (&element);
5218
5219         indices [0] = 1;
5220         indices [1] = 1;
5221         indices [2] = 1;
5222         element.vt = VT_I4;
5223         element.lVal = 111;
5224         SafeArrayPutElement (safearray, indices, &element);
5225         VariantClear (&element);
5226
5227         indices [0] = 0;
5228         indices [1] = 1;
5229         indices [2] = 0;
5230         element.vt = VT_BSTR;
5231         element.bstrVal = marshal_bstr_alloc("ABCDEFG");
5232         SafeArrayPutElement (safearray, indices, &element);
5233         VariantClear (&element);
5234
5235         return hr;
5236 }
5237
5238 LIBTEST_API int STDCALL 
5239 mono_test_marshal_safearray_mixed(
5240                 SAFEARRAY  *safearray1,
5241                 SAFEARRAY **safearray2,
5242                 SAFEARRAY  *safearray3,
5243                 SAFEARRAY **safearray4
5244                 )
5245 {
5246         HRESULT hr = S_OK;
5247
5248         /* Initialize out parameters */
5249         *safearray2 = NULL;
5250
5251         /* array1: Check that in array is one dimensional and contains the expected value */
5252         hr = mono_test_marshal_safearray_in_out_byval_1dim_vt_i4 (safearray1);
5253
5254         /* array2: Fill in with some values to check on the managed side */
5255         if (hr == S_OK)
5256                 hr = mono_test_marshal_safearray_out_1dim_vt_bstr (safearray2);
5257
5258         /* array3: Check that in array is one dimensional and contains the expected value */
5259         if (hr == S_OK)
5260                 hr = mono_test_marshal_safearray_in_byval_1dim_vt_mixed(safearray3);
5261
5262         /* array4: Check input values and fill in with some values to check on the managed side */
5263         if (hr == S_OK)
5264                 hr = mono_test_marshal_safearray_in_out_byref_3dim_vt_bstr(safearray4);
5265
5266         return hr;
5267 }
5268
5269 #endif
5270
5271 static int call_managed_res;
5272
5273 static void
5274 call_managed (gpointer arg)
5275 {
5276         SimpleDelegate del = arg;
5277
5278         call_managed_res = del (42);
5279 }
5280
5281 LIBTEST_API int STDCALL 
5282 mono_test_marshal_thread_attach (SimpleDelegate del)
5283 {
5284 #ifdef WIN32
5285         return 43;
5286 #else
5287         int res;
5288         pthread_t t;
5289
5290         res = pthread_create (&t, NULL, (gpointer)call_managed, del);
5291         g_assert (res == 0);
5292         pthread_join (t, NULL);
5293
5294         return call_managed_res;
5295 #endif
5296 }
5297
5298 typedef int (STDCALL *Callback) (void);
5299
5300 static Callback callback;
5301
5302 LIBTEST_API void STDCALL 
5303 mono_test_marshal_set_callback (Callback cb)
5304 {
5305         callback = cb;
5306 }
5307
5308 LIBTEST_API int STDCALL 
5309 mono_test_marshal_call_callback (void)
5310 {
5311         return callback ();
5312 }
5313
5314 LIBTEST_API int STDCALL
5315 mono_test_marshal_lpstr (char *str)
5316 {
5317         return strcmp ("ABC", str);
5318 }
5319
5320 LIBTEST_API int STDCALL
5321 mono_test_marshal_lpwstr (gunichar2 *str)
5322 {
5323         char *s;
5324         int res;
5325
5326         s = g_utf16_to_utf8 (str, -1, NULL, NULL, NULL);
5327         res = strcmp ("ABC", s);
5328         g_free (s);
5329
5330         return res;
5331 }
5332
5333 LIBTEST_API char* STDCALL
5334 mono_test_marshal_return_lpstr (void)
5335 {
5336         char *res = marshal_alloc (4);
5337         strcpy (res, "XYZ");
5338         return res;
5339 }
5340
5341
5342 LIBTEST_API gunichar2* STDCALL
5343 mono_test_marshal_return_lpwstr (void)
5344 {
5345         gunichar2 *res = marshal_alloc (8);
5346         gunichar2* tmp = g_utf8_to_utf16 ("XYZ", -1, NULL, NULL, NULL);
5347
5348         memcpy (res, tmp, 8);
5349         g_free (tmp);
5350
5351         return res;
5352 }
5353
5354 typedef struct {
5355         double d;
5356 } SingleDoubleStruct;
5357
5358 LIBTEST_API SingleDoubleStruct STDCALL
5359 mono_test_marshal_return_single_double_struct (void)
5360 {
5361         SingleDoubleStruct res;
5362
5363         res.d = 3.0;
5364
5365         return res;
5366 }
5367
5368
5369 #ifndef TARGET_X86
5370
5371 LIBTEST_API int STDCALL
5372 mono_test_has_thiscall (void)
5373 {
5374         return 1;
5375 }
5376
5377 LIBTEST_API int
5378 _mono_test_native_thiscall1 (int arg)
5379 {
5380         return arg;
5381 }
5382
5383 LIBTEST_API int
5384 _mono_test_native_thiscall2 (int arg, int arg2)
5385 {
5386         return arg + (arg2^1);
5387 }
5388
5389 LIBTEST_API int
5390 _mono_test_native_thiscall3 (int arg, int arg2, int arg3)
5391 {
5392         return arg + (arg2^1) + (arg3^2);
5393 }
5394
5395 #elif defined(__GNUC__)
5396
5397 LIBTEST_API int STDCALL
5398 mono_test_has_thiscall (void)
5399 {
5400         return 1;
5401 }
5402
5403 #define def_asm_fn(name) \
5404         "\t.align 4\n" \
5405         "\t.globl _" #name "\n" \
5406         "_" #name ":\n" \
5407         "\t.globl __" #name "\n" \
5408         "__" #name ":\n"
5409
5410 asm(".text\n"
5411
5412 def_asm_fn(mono_test_native_thiscall1)
5413 "\tmovl %ecx,%eax\n"
5414 "\tret\n"
5415
5416 def_asm_fn(mono_test_native_thiscall2)
5417 "\tmovl %ecx,%eax\n"
5418 "\tmovl 4(%esp),%ecx\n"
5419 "\txorl $1,%ecx\n"
5420 "\taddl %ecx,%eax\n"
5421 "\tret $4\n"
5422
5423 def_asm_fn(mono_test_native_thiscall3)
5424 "\tmovl %ecx,%eax\n"
5425 "\tmovl 4(%esp),%ecx\n"
5426 "\txorl $1,%ecx\n"
5427 "\taddl %ecx,%eax\n"
5428 "\tmovl 8(%esp),%ecx\n"
5429 "\txorl $2,%ecx\n"
5430 "\taddl %ecx,%eax\n"
5431 "\tret $8\n"
5432
5433 );
5434
5435 #else
5436
5437 LIBTEST_API int STDCALL
5438 mono_test_has_thiscall (void)
5439 {
5440         return 0;
5441 }
5442
5443 #endif
5444