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