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