New test.
[mono.git] / mono / tests / libtest.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <glib.h>
5 #include <errno.h>
6 #include <time.h>
7
8 #ifdef WIN32
9 #include <windows.h>
10 #include "initguid.h"
11 #endif
12
13 #ifdef WIN32
14 #define STDCALL __stdcall
15 #else
16 #define STDCALL
17 #endif
18
19 #ifdef WIN32
20 extern __declspec(dllimport) __stdcall void CoTaskMemFree(void *ptr);
21 #endif
22
23 typedef int (STDCALL *SimpleDelegate) (int a);
24
25 static void marshal_free (void *ptr)
26 {
27 #ifdef WIN32
28         CoTaskMemFree (ptr);
29 #else
30         g_free (ptr);
31 #endif
32 }
33
34 STDCALL unsigned short*
35 test_lpwstr_marshal (unsigned short* chars, long length)
36 {
37         int i = 0;
38         unsigned short *res;
39
40         res = malloc (2 * (length + 1));
41
42         // printf("test_lpwstr_marshal()\n");
43         
44         while ( i < length ) {
45                 // printf("X|%u|\n", chars[i]);
46                 res [i] = chars[i];
47                 i++;
48         }
49
50         res [i] = 0;
51
52         return res;
53 }
54
55 typedef struct {
56         int b;
57         int a;
58         int c;
59 } union_test_1_type;
60
61 STDCALL int 
62 mono_union_test_1 (union_test_1_type u1) {
63         // printf ("Got values %d %d %d\n", u1.b, u1.a, u1.c);
64         return u1.a + u1.b + u1.c;
65 }
66
67 STDCALL int 
68 mono_return_int (int a) {
69         // printf ("Got value %d\n", a);
70         return a;
71 }
72
73 struct ss
74 {
75         int i;
76 };
77
78 STDCALL int 
79 mono_return_int_ss (struct ss a) {
80         // printf ("Got value %d\n", a.i);
81         return a.i;
82 }
83
84 STDCALL struct ss 
85 mono_return_ss (struct ss a) {
86         // printf ("Got value %d\n", a.i);
87         a.i++;
88         return a;
89 }
90
91 struct sc1
92 {
93         char c[1];
94 };
95
96 STDCALL struct sc1 
97 mono_return_sc1 (struct sc1 a) {
98         // printf ("Got value %d\n", a.c[0]);
99         a.c[0]++;
100         return a;
101 }
102
103
104 struct sc3
105 {
106         char c[3];
107 };
108
109 STDCALL struct sc3 
110 mono_return_sc3 (struct sc3 a) {
111         // printf ("Got values %d %d %d\n", a.c[0], a.c[1], a.c[2]);
112         a.c[0]++;
113         a.c[1] += 2;
114         a.c[2] += 3;
115         return a;
116 }
117
118 struct sc5
119 {
120         char c[5];
121 };
122
123 STDCALL struct sc5 
124 mono_return_sc5 (struct sc5 a) {
125         // printf ("Got values %d %d %d %d %d\n", a.c[0], a.c[1], a.c[2], a.c[3], a.c[4]);
126         a.c[0]++;
127         a.c[1] += 2;
128         a.c[2] += 3;
129         a.c[3] += 4;
130         a.c[4] += 5;
131         return a;
132 }
133
134 union su
135 {
136         int i1;
137         int i2;
138 };
139
140 STDCALL int 
141 mono_return_int_su (union su a) {
142         // printf ("Got value %d\n", a.i1);
143         return a.i1;
144 }
145
146 STDCALL int 
147 mono_test_many_int_arguments (int a, int b, int c, int d, int e,
148                                                           int f, int g, int h, int i, int j);
149 STDCALL short 
150 mono_test_many_short_arguments (short a, short b, short c, short d, short e,
151                                                                 short f, short g, short h, short i, short j);
152 STDCALL char 
153 mono_test_many_char_arguments (char a, char b, char c, char d, char e,
154                                                            char f, char g, char h, char i, char j);
155
156 STDCALL int
157 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)
158 {
159         return a + b + c + d + e + f + g + h + i + j;
160 }
161
162 STDCALL short
163 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)
164 {
165         return a + b + c + d + e + f + g + h + i + j;
166 }
167
168 STDCALL char
169 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)
170 {
171         return a + b + c + d + e + f + g + h + i + j;
172 }
173
174 STDCALL float
175 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)
176 {
177         return a + b + c + d + e + f + g + h + i + j;
178 }
179
180 STDCALL double
181 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)
182 {
183         return a + b + c + d + e + f + g + h + i + j;
184 }
185
186 STDCALL double
187 mono_test_split_double_arguments (double a, double b, float c, double d, double e)
188 {
189         return a + b + c + d + e;
190 }
191
192 STDCALL int
193 mono_test_puts_static (char *s)
194 {
195         // printf ("TEST %s\n", s);
196         return 1;
197 }
198
199 typedef int (STDCALL *SimpleDelegate3) (int a, int b);
200
201 STDCALL int
202 mono_invoke_delegate (SimpleDelegate3 delegate)
203 {
204         int res;
205
206         // printf ("start invoke %p\n", delegate);
207
208         res = delegate (2, 3);
209
210         // printf ("end invoke\n");
211
212         return res;
213 }
214
215 STDCALL int 
216 mono_test_marshal_char (short a1)
217 {
218         if (a1 == 'a')
219                 return 0;
220         
221         return 1;
222 }
223
224 STDCALL void
225 mono_test_marshal_char_array (gunichar2 *s)
226 {
227         const char m[] = "abcdef";
228         gunichar2* s2;
229         glong len;
230
231         s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
232         
233         len = (len * 2) + 2;
234         memcpy (s, s2, len);
235
236         g_free (s2);
237 }
238
239 STDCALL int
240 mono_test_empty_pinvoke (int i)
241 {
242         return i;
243 }
244
245 STDCALL int 
246 mono_test_marshal_bool_byref (int a, int *b, int c)
247 {
248     int res = *b;
249
250         *b = 1;
251
252         return res;
253 }
254
255 STDCALL int 
256 mono_test_marshal_array (int *a1)
257 {
258         int i, sum = 0;
259
260         for (i = 0; i < 50; i++)
261                 sum += a1 [i];
262         
263         return sum;
264 }
265
266 STDCALL int 
267 mono_test_marshal_inout_array (int *a1)
268 {
269         int i, sum = 0;
270
271         for (i = 0; i < 50; i++) {
272                 sum += a1 [i];
273                 a1 [i] = 50 - a1 [i];
274         }
275         
276         return sum;
277 }
278
279 STDCALL int 
280 mono_test_marshal_out_array (int *a1)
281 {
282         int i;
283
284         for (i = 0; i < 50; i++) {
285                 a1 [i] = i;
286         }
287         
288         return 0;
289 }
290
291 STDCALL int 
292 mono_test_marshal_inout_nonblittable_array (gunichar2 *a1)
293 {
294         int i, sum = 0;
295
296         for (i = 0; i < 10; i++) {
297                 a1 [i] = 'F';
298         }
299         
300         return sum;
301 }
302
303 typedef struct {
304         int a;
305         int b;
306         int c;
307         const char *d;
308         gunichar2 *d2;
309 } simplestruct;
310
311 typedef struct {
312         double x;
313         double y;
314 } point;
315
316 STDCALL simplestruct
317 mono_test_return_vtype (int i)
318 {
319         simplestruct res;
320         static gunichar2 test2 [] = { 'T', 'E', 'S', 'T', '2', 0 };
321
322         res.a = 0;
323         res.b = 1;
324         res.c = 0;
325         res.d = "TEST";
326         res.d2 = test2;
327
328         return res;
329 }
330
331 STDCALL void
332 mono_test_delegate_struct (void)
333 {
334         // printf ("TEST\n");
335 }
336
337 typedef char* (STDCALL *ReturnStringDelegate) (const char *s);
338
339 STDCALL char *
340 mono_test_return_string (ReturnStringDelegate func)
341 {
342         char *res;
343
344         // printf ("mono_test_return_string\n");
345
346         res = func ("TEST");
347         marshal_free (res);
348
349         // printf ("got string: %s\n", res);
350         return g_strdup ("12345");
351 }
352
353 typedef int (STDCALL *RefVTypeDelegate) (int a, simplestruct *ss, int b);
354
355 STDCALL int
356 mono_test_ref_vtype (int a, simplestruct *ss, int b, RefVTypeDelegate func)
357 {
358         if (a == 1 && b == 2 && ss->a == 0 && ss->b == 1 && ss->c == 0 &&
359             !strcmp (ss->d, "TEST1")) {
360                 ss->a = 1;
361                 ss->b = 0;
362                 ss->c = 1;
363                 ss->d = "TEST2";
364
365                 return func (a, ss, b);
366         }
367
368         return 1;
369 }
370
371 typedef int (STDCALL *OutVTypeDelegate) (int a, simplestruct *ss, int b);
372
373 STDCALL int
374 mono_test_marshal_out_struct (int a, simplestruct *ss, int b, OutVTypeDelegate func)
375 {
376         /* Check that the input pointer is ignored */
377         ss->d = (gpointer)0x12345678;
378
379         func (a, ss, b);
380
381         if (ss->a && ss->b && ss->c && !strcmp (ss->d, "TEST3"))
382                 return 0;
383         else
384                 return 1;
385 }
386
387 typedef struct {
388         int a;
389         SimpleDelegate func, func2;
390 } DelegateStruct;
391
392 STDCALL DelegateStruct
393 mono_test_marshal_delegate_struct (DelegateStruct ds)
394 {
395         DelegateStruct res;
396
397         res.a = ds.func (ds.a) + ds.func2 (ds.a);
398         res.func = ds.func;
399         res.func2 = ds.func2;
400
401         return res;
402 }
403
404 STDCALL int 
405 mono_test_marshal_struct (simplestruct ss)
406 {
407         if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
408             !strcmp (ss.d, "TEST"))
409                 return 0;
410
411         return 1;
412 }
413
414 STDCALL int
415 mono_test_marshal_byref_struct (simplestruct *ss, int a, int b, int c, char *d)
416 {
417         gboolean res = (ss->a == a && ss->b == b && ss->c == c && strcmp (ss->d, d) == 0);
418
419         ss->a = !ss->a;
420         ss->b = !ss->b;
421         ss->c = !ss->c;
422         ss->d = g_strdup ("DEF");
423
424         return res ? 0 : 1;
425 }
426
427 typedef struct {
428         int a;
429         int b;
430         int c;
431         char *d;
432         unsigned char e;
433         double f;
434         unsigned char g;
435         guint64 h;
436 } simplestruct2;
437
438 STDCALL int
439 mono_test_marshal_struct2 (simplestruct2 ss)
440 {
441         if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
442             !strcmp (ss.d, "TEST") && 
443             ss.e == 99 && ss.f == 1.5 && ss.g == 42 && ss.h == (guint64)123)
444                 return 0;
445
446         return 1;
447 }
448
449 /* on HP some of the struct should be on the stack and not in registers */
450 STDCALL int
451 mono_test_marshal_struct2_2 (int i, int j, int k, simplestruct2 ss)
452 {
453         if (i != 10 || j != 11 || k != 12)
454                 return 1;
455         if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
456             !strcmp (ss.d, "TEST") && 
457             ss.e == 99 && ss.f == 1.5 && ss.g == 42 && ss.h == (guint64)123)
458                 return 0;
459
460         return 1;
461 }
462
463 STDCALL int 
464 mono_test_marshal_lpstruct (simplestruct *ss)
465 {
466         if (ss->a == 0 && ss->b == 1 && ss->c == 0 &&
467             !strcmp (ss->d, "TEST"))
468                 return 0;
469
470         return 1;
471 }
472
473 STDCALL int 
474 mono_test_marshal_lpstruct_blittable (point *p)
475 {
476         if (p->x == 1.0 && p->y == 2.0)
477                 return 0;
478         else
479                 return 1;
480 }
481
482 STDCALL int
483 mono_test_marshal_struct_array (simplestruct2 *ss)
484 {
485         if (! (ss[0].a == 0 && ss[0].b == 1 && ss[0].c == 0 &&
486                    !strcmp (ss[0].d, "TEST") && 
487                    ss[0].e == 99 && ss[0].f == 1.5 && ss[0].g == 42 && ss[0].h == (guint64)123))
488                 return 1;
489
490         if (! (ss[1].a == 0 && ss[1].b == 0 && ss[1].c == 0 &&
491                    !strcmp (ss[1].d, "TEST2") && 
492                    ss[1].e == 100 && ss[1].f == 2.5 && ss[1].g == 43 && ss[1].h == (guint64)124))
493                 return 1;
494
495         return 0;
496 }
497
498 typedef struct long_align_struct {
499         gint32 a;
500         gint64 b;
501         gint64 c;
502 } long_align_struct;
503
504 STDCALL int
505 mono_test_marshal_long_align_struct_array (long_align_struct *ss)
506 {
507         return ss[0].a + ss[0].b + ss[0].c + ss[1].a + ss[1].b + ss[1].c;
508 }
509
510 STDCALL simplestruct2 *
511 mono_test_marshal_class (int i, int j, int k, simplestruct2 *ss, int l)
512 {
513         simplestruct2 *res;
514
515         if (!ss)
516                 return NULL;
517
518         if (i != 10 || j != 11 || k != 12 || l != 14)
519                 return NULL;
520         if (! (ss->a == 0 && ss->b == 1 && ss->c == 0 &&
521                    !strcmp (ss->d, "TEST") && 
522                    ss->e == 99 && ss->f == 1.5 && ss->g == 42 && ss->h == (guint64)123))
523                 return NULL;
524
525         res = g_new0 (simplestruct2, 1);
526         memcpy (res, ss, sizeof (simplestruct2));
527         res->d = g_strdup ("TEST");
528         return res;
529 }
530
531 STDCALL int
532 mono_test_marshal_byref_class (simplestruct2 **ssp)
533 {
534         simplestruct2 *ss = *ssp;
535         simplestruct2 *res;
536         
537         if (! (ss->a == 0 && ss->b == 1 && ss->c == 0 &&
538                    !strcmp (ss->d, "TEST") && 
539                    ss->e == 99 && ss->f == 1.5 && ss->g == 42 && ss->h == (guint64)123))
540                 return 1;
541
542         res = g_new0 (simplestruct2, 1);
543         memcpy (res, ss, sizeof (simplestruct2));
544         res->d = g_strdup ("TEST-RES");
545
546         *ssp = res;
547         return 0;
548 }
549
550 static void *
551 get_sp (void)
552 {
553         int i;
554         void *p;
555
556         /* Yes, this is correct, we are only trying to determine the value of the stack here */
557         p = &i;
558         return p;
559 }
560
561 STDCALL int
562 reliable_delegate (int a)
563 {
564         return a;
565 }
566
567 /*
568  * Checks whether get_sp() works as expected. It doesn't work with gcc-2.95.3 on linux.
569  */
570 static gboolean
571 is_get_sp_reliable (void)
572 {
573         void *sp1, *sp2;
574
575         reliable_delegate(1);
576         sp1 = get_sp();
577         reliable_delegate(1);
578         sp2 = get_sp();
579         return sp1 == sp2;
580
581
582 STDCALL int
583 mono_test_marshal_delegate (SimpleDelegate delegate)
584 {
585         void *sp1, *sp2;
586
587         /* Check that the delegate wrapper is stdcall */
588         delegate (2);
589         sp1 = get_sp ();
590         delegate (2);
591         sp2 = get_sp ();
592         if (is_get_sp_reliable())
593                 g_assert (sp1 == sp2);
594
595         return delegate (2);
596 }
597
598 STDCALL SimpleDelegate
599 mono_test_marshal_return_delegate (SimpleDelegate delegate)
600 {
601         return delegate;
602 }
603
604 static STDCALL int
605 return_plus_one (int i)
606 {
607         return i + 1;
608 }
609
610 STDCALL SimpleDelegate
611 mono_test_marshal_return_delegate_2 ()
612 {
613         return return_plus_one;
614 }
615
616 typedef simplestruct (STDCALL *SimpleDelegate2) (simplestruct ss);
617
618 static gboolean
619 is_utf16_equals (gunichar2 *s1, const char *s2)
620 {
621         char *s;
622         int res;
623
624         s = g_utf16_to_utf8 (s1, -1, NULL, NULL, NULL);
625         res = strcmp (s, s2);
626         g_free (s);
627
628         return res == 0;
629 }
630
631 STDCALL int
632 mono_test_marshal_delegate2 (SimpleDelegate2 delegate)
633 {
634         simplestruct ss, res;
635
636         ss.a = 0;
637         ss.b = 1;
638         ss.c = 0;
639         ss.d = "TEST";
640         ss.d2 = g_utf8_to_utf16 ("TEST2", -1, NULL, NULL, NULL); 
641
642         res = delegate (ss);
643         if (! (res.a && !res.b && res.c && !strcmp (res.d, "TEST-RES") && is_utf16_equals (res.d2, "TEST2-RES")))
644                 return 1;
645
646         return 0;
647 }
648
649 typedef simplestruct* (STDCALL *SimpleDelegate4) (simplestruct *ss);
650
651 STDCALL int
652 mono_test_marshal_delegate4 (SimpleDelegate4 delegate)
653 {
654         simplestruct ss;
655         simplestruct *res;
656
657         ss.a = 0;
658         ss.b = 1;
659         ss.c = 0;
660         ss.d = "TEST";
661
662         /* Check argument */
663         res = delegate (&ss);
664         if (!res)
665                 return 1;
666
667         /* Check return value */
668         if (! (!res->a && res->b && !res->c && !strcmp (res->d, "TEST")))
669                 return 2;
670
671         /* Check NULL argument and NULL result */
672         res = delegate (NULL);
673         if (res)
674                 return 3;
675
676         return 0;
677 }
678
679 typedef int (STDCALL *SimpleDelegate5) (simplestruct **ss);
680
681 STDCALL int
682 mono_test_marshal_delegate5 (SimpleDelegate5 delegate)
683 {
684         simplestruct ss;
685         int res;
686         simplestruct *ptr;
687
688         ss.a = 0;
689         ss.b = 1;
690         ss.c = 0;
691         ss.d = "TEST";
692
693         ptr = &ss;
694
695         res = delegate (&ptr);
696         if (res != 0)
697                 return 1;
698
699         if (!(ptr->a && !ptr->b && ptr->c && !strcmp (ptr->d, "RES")))
700                 return 2;
701
702         return 0;
703 }
704
705 STDCALL int
706 mono_test_marshal_delegate6 (SimpleDelegate5 delegate)
707 {
708         int res;
709
710         res = delegate (NULL);
711
712         return 0;
713 }
714
715 typedef int (STDCALL *SimpleDelegate7) (simplestruct **ss);
716
717 STDCALL int
718 mono_test_marshal_delegate7 (SimpleDelegate7 delegate)
719 {
720         int res;
721         simplestruct *ptr;
722
723         /* Check that the input pointer is ignored */
724         ptr = (gpointer)0x12345678;
725
726         res = delegate (&ptr);
727         if (res != 0)
728                 return 1;
729
730         if (!(ptr->a && !ptr->b && ptr->c && !strcmp (ptr->d, "RES")))
731                 return 2;
732
733         return 0;
734 }
735
736 typedef int (STDCALL *InOutByvalClassDelegate) (simplestruct *ss);
737
738 STDCALL int
739 mono_test_marshal_inout_byval_class_delegate (InOutByvalClassDelegate delegate)
740 {
741         int res;
742         simplestruct ss;
743
744         ss.a = FALSE;
745         ss.b = TRUE;
746         ss.c = FALSE;
747         ss.d = g_strdup_printf ("%s", "FOO");
748
749         res = delegate (&ss);
750         if (res != 0)
751                 return 1;
752
753         if (!(ss.a && !ss.b && ss.c && !strcmp (ss.d, "RES")))
754                 return 2;
755
756         return 0;
757 }
758
759 typedef int (STDCALL *SimpleDelegate8) (gunichar2 *s);
760
761 STDCALL int
762 mono_test_marshal_delegate8 (SimpleDelegate8 delegate, gunichar2 *s)
763 {
764         return delegate (s);
765 }
766
767 typedef int (STDCALL *return_int_fnt) (int i);
768 typedef int (STDCALL *SimpleDelegate9) (return_int_fnt d);
769
770 STDCALL int
771 mono_test_marshal_delegate9 (SimpleDelegate9 delegate, gpointer ftn)
772 {
773         return delegate (ftn);
774 }
775
776 STDCALL static int
777 return_self (int i)
778 {
779         return i;
780 }
781
782 STDCALL int
783 mono_test_marshal_delegate10 (SimpleDelegate9 delegate)
784 {
785         return delegate (return_self);
786 }
787
788 typedef int (STDCALL *PrimitiveByrefDelegate) (int *i);
789
790 STDCALL int
791 mono_test_marshal_primitive_byref_delegate (PrimitiveByrefDelegate delegate)
792 {
793         int i = 1;
794
795         int res = delegate (&i);
796         if (res != 0)
797                 return res;
798
799         if (i != 2)
800                 return 2;
801
802         return 0;
803 }
804
805 typedef int (STDCALL *return_int_delegate) (int i);
806
807 typedef return_int_delegate (STDCALL *ReturnDelegateDelegate) (void);
808
809 STDCALL int
810 mono_test_marshal_return_delegate_delegate (ReturnDelegateDelegate d)
811 {
812         return (d ()) (55);
813 }
814
815 STDCALL int 
816 mono_test_marshal_stringbuilder (char *s, int n)
817 {
818         const char m[] = "This is my message.  Isn't it nice?";
819
820         if (strcmp (s, "ABCD") != 0)
821                 return 1;
822         strncpy(s, m, n);
823         s [n] = '\0';
824         return 0;
825 }
826
827 STDCALL int 
828 mono_test_marshal_stringbuilder_default (char *s, int n)
829 {
830         const char m[] = "This is my message.  Isn't it nice?";
831
832         strncpy(s, m, n);
833         s [n] = '\0';
834         return 0;
835 }
836
837 STDCALL int 
838 mono_test_marshal_stringbuilder_unicode (gunichar2 *s, int n)
839 {
840         const char m[] = "This is my message.  Isn't it nice?";
841         gunichar2* s2;
842         glong len;
843
844         s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
845         
846         len = (len * 2) + 2;
847         if (len > (n * 2))
848                 len = n * 2;
849         memcpy (s, s2, len);
850
851         g_free (s2);
852
853         return 0;
854 }
855
856 typedef struct {
857 #ifndef __GNUC__
858     char a;
859 #endif
860 } EmptyStruct;
861
862 STDCALL int
863 mono_test_marshal_empty_string_array (char **array)
864 {
865         return (array == NULL) ? 0 : 1;
866 }
867
868 STDCALL int
869 mono_test_marshal_string_array (char **array)
870 {
871         if (strcmp (array [0], "ABC"))
872                 return 1;
873         if (strcmp (array [1], "DEF"))
874                 return 2;
875
876         if (array [2] != NULL)
877                 return 3;
878
879         return 0;
880 }
881
882 STDCALL int
883 mono_test_marshal_byref_string_array (char ***array)
884 {
885         if (*array == NULL)
886                 return 0;
887
888         if (strcmp ((*array) [0], "Alpha"))
889                 return 2;
890         if (strcmp ((*array) [1], "Beta"))
891                 return 2;
892         if (strcmp ((*array) [2], "Gamma"))
893                 return 2;
894
895         return 1;
896 }
897
898 STDCALL int
899 mono_test_marshal_stringbuilder_array (char **array)
900 {
901         if (strcmp (array [0], "ABC"))
902                 return 1;
903         if (strcmp (array [1], "DEF"))
904                 return 2;
905
906         strcpy (array [0], "DEF");
907         strcpy (array [1], "ABC");
908
909         return 0;
910 }
911
912 STDCALL int
913 mono_test_marshal_unicode_string_array (gunichar2 **array, char **array2)
914 {
915         GError *error = NULL;
916         char *s;
917         
918         s = g_utf16_to_utf8 (array [0], -1, NULL, NULL, &error);
919         if (strcmp (s, "ABC")) {
920                 g_free (s);
921                 return 1;
922         }
923         else
924                 g_free (s);
925
926         s = g_utf16_to_utf8 (array [1], -1, NULL, NULL, &error);
927         if (strcmp (s, "DEF")) {
928                 g_free (s);
929                 return 2;
930         }
931         else
932                 g_free (s);
933
934         if (strcmp (array2 [0], "ABC"))
935                 return 3;
936
937         if (strcmp (array2 [1], "DEF")) 
938                 return 4;
939
940         return 0;
941 }
942
943 /* this does not work on Redhat gcc 2.96 */
944 STDCALL int 
945 mono_test_empty_struct (int a, EmptyStruct es, int b)
946 {
947         // printf ("mono_test_empty_struct %d %d\n", a, b);
948
949         // Intel icc on ia64 passes 'es' in 2 registers
950 #if defined(__ia64) && defined(__INTEL_COMPILER)
951         return 0;
952 #else
953         if (a == 1 && b == 2)
954                 return 0;
955         return 1;
956 #endif
957 }
958
959 typedef struct {
960        char a[100];
961 } ByValStrStruct;
962
963 STDCALL ByValStrStruct *
964 mono_test_byvalstr_gen (void)
965 {
966         ByValStrStruct *ret;
967        
968         ret = malloc(sizeof(ByValStrStruct));
969         memset(ret, 'a', sizeof(ByValStrStruct)-1);
970         ret->a[sizeof(ByValStrStruct)-1] = 0;
971
972         return ret;
973 }
974
975 STDCALL int
976 mono_test_byvalstr_check (ByValStrStruct* data, char* correctString)
977 {
978         int ret;
979
980         ret = strcmp(data->a, correctString);
981         // printf ("T1: %s\n", data->a);
982         // printf ("T2: %s\n", correctString);
983
984         marshal_free (data);
985         return (ret != 0);
986 }
987
988 STDCALL int
989 NameManglingAnsi (char *data)
990 {
991         return data [0] + data [1] + data [2];
992 }
993
994 STDCALL int
995 NameManglingAnsiA (char *data)
996 {
997         g_assert_not_reached ();
998 }
999
1000 STDCALL int
1001 NameManglingAnsiW (char *data)
1002 {
1003         g_assert_not_reached ();
1004 }
1005
1006 STDCALL int
1007 NameManglingAnsi2A (char *data)
1008 {
1009         return data [0] + data [1] + data [2];
1010 }
1011
1012 STDCALL int
1013 NameManglingAnsi2W (char *data)
1014 {
1015         g_assert_not_reached ();
1016 }
1017
1018 STDCALL int
1019 NameManglingUnicode (char *data)
1020 {
1021         g_assert_not_reached ();
1022 }
1023
1024 STDCALL int
1025 NameManglingUnicodeW (gunichar2 *data)
1026 {
1027         return data [0] + data [1] + data [2];
1028 }
1029
1030 STDCALL int
1031 NameManglingUnicode2 (gunichar2 *data)
1032 {
1033         return data [0] + data [1] + data [2];
1034 }
1035
1036 STDCALL int
1037 NameManglingAutoW (char *data)
1038 {
1039 #ifdef WIN32
1040         return (data [0] + data [1] + data [2]) == 131 ? 0 : 1;
1041 #else
1042         g_assert_not_reached ();
1043 #endif
1044 }
1045
1046 STDCALL int
1047 NameManglingAuto (char *data)
1048 {
1049 #ifndef WIN32
1050         return (data [0] + data [1] + data [2]) == 198 ? 0 : 1;
1051 #else
1052         g_assert_not_reached ();
1053 #endif
1054 }
1055
1056 typedef int (STDCALL *intcharFunc)(const char*);
1057
1058 STDCALL void 
1059 callFunction (intcharFunc f)
1060 {
1061         f ("ABC");
1062 }
1063
1064 typedef struct {
1065         const char* str;
1066         int i;
1067 } SimpleObj;
1068
1069 STDCALL int
1070 class_marshal_test0 (SimpleObj *obj1)
1071 {
1072         // printf ("class_marshal_test0 %s %d\n", obj1->str, obj1->i);
1073
1074         if (strcmp(obj1->str, "T1"))
1075                 return -1;
1076         if (obj1->i != 4)
1077                 return -2;
1078
1079         return 0;
1080 }
1081
1082 STDCALL int
1083 class_marshal_test4 (SimpleObj *obj1)
1084 {
1085         if (obj1)
1086                 return -1;
1087
1088         return 0;
1089 }
1090
1091 STDCALL void
1092 class_marshal_test1 (SimpleObj **obj1)
1093 {
1094         SimpleObj *res = malloc (sizeof (SimpleObj));
1095
1096         res->str = g_strdup ("ABC");
1097         res->i = 5;
1098
1099         *obj1 = res;
1100 }
1101
1102 STDCALL int
1103 class_marshal_test2 (SimpleObj **obj1)
1104 {
1105         // printf ("class_marshal_test2 %s %d\n", (*obj1)->str, (*obj1)->i);
1106
1107         if (strcmp((*obj1)->str, "ABC"))
1108                 return -1;
1109         if ((*obj1)->i != 5)
1110                 return -2;
1111
1112         return 0;
1113 }
1114
1115 STDCALL int
1116 string_marshal_test0 (char *str)
1117 {
1118         if (strcmp (str, "TEST0"))
1119                 return -1;
1120
1121         return 0;
1122 }
1123
1124 STDCALL void
1125 string_marshal_test1 (const char **str)
1126 {
1127         *str = "TEST1";
1128 }
1129
1130 STDCALL int
1131 string_marshal_test2 (char **str)
1132 {
1133         // printf ("string_marshal_test2 %s\n", *str);
1134
1135         if (strcmp (*str, "TEST1"))
1136                 return -1;
1137
1138         return 0;
1139 }
1140
1141 STDCALL int
1142 string_marshal_test3 (char *str)
1143 {
1144         if (str)
1145                 return -1;
1146
1147         return 0;
1148 }
1149
1150 typedef struct {
1151         int a;
1152         int b;
1153 } BlittableClass;
1154
1155 STDCALL BlittableClass* 
1156 TestBlittableClass (BlittableClass *vl)
1157 {
1158         BlittableClass *res;
1159
1160         // printf ("TestBlittableClass %d %d\n", vl->a, vl->b);
1161
1162         if (vl) {
1163                 vl->a++;
1164                 vl->b++;
1165
1166                 res = g_new0 (BlittableClass, 1);
1167                 memcpy (res, vl, sizeof (BlittableClass));
1168         } else {
1169                 res = g_new0 (BlittableClass, 1);
1170                 res->a = 42;
1171                 res->b = 43;
1172         }
1173
1174         return res;
1175 }
1176
1177 typedef struct OSVERSIONINFO_STRUCT
1178
1179         int a; 
1180         int b; 
1181 } OSVERSIONINFO_STRUCT;
1182
1183 STDCALL int 
1184 MyGetVersionEx (OSVERSIONINFO_STRUCT *osvi)
1185 {
1186
1187         // printf ("GOT %d %d\n", osvi->a, osvi->b);
1188
1189         osvi->a += 1;
1190         osvi->b += 1;
1191
1192         return osvi->a + osvi->b;
1193 }
1194
1195 STDCALL int 
1196 BugGetVersionEx (int a, int b, int c, int d, int e, int f, int g, int h, OSVERSIONINFO_STRUCT *osvi)
1197 {
1198
1199         // printf ("GOT %d %d\n", osvi->a, osvi->b);
1200
1201         osvi->a += 1;
1202         osvi->b += 1;
1203
1204         return osvi->a + osvi->b;
1205 }
1206
1207 STDCALL int
1208 mono_test_marshal_point (point pt)
1209 {
1210         // printf("point %g %g\n", pt.x, pt.y);
1211         if (pt.x == 1.25 && pt.y == 3.5)
1212                 return 0;
1213
1214         return 1;
1215 }
1216
1217 typedef struct {
1218         int x;
1219         double y;
1220 } mixed_point;
1221
1222 STDCALL int
1223 mono_test_marshal_mixed_point (mixed_point pt)
1224 {
1225         // printf("mixed point %d %g\n", pt.x, pt.y);
1226         if (pt.x == 5 && pt.y == 6.75)
1227                 return 0;
1228
1229         return 1;
1230 }
1231
1232 STDCALL int
1233 mono_test_marshal_mixed_point_2 (mixed_point *pt)
1234 {
1235         if (pt->x != 5 || pt->y != 6.75)
1236                 return 1;
1237
1238         pt->x = 10;
1239         pt->y = 12.35;
1240
1241         return 0;
1242 }
1243
1244 STDCALL int 
1245 marshal_test_ref_bool(int i, char *b1, short *b2, int *b3)
1246 {
1247     int res = 1;
1248     if (*b1 != 0 && *b1 != 1)
1249         return 1;
1250     if (*b2 != 0 && *b2 != -1) /* variant_bool */
1251         return 1;
1252     if (*b3 != 0 && *b3 != 1)
1253         return 1;
1254     if (i == ((*b1 << 2) | (-*b2 << 1) | *b3))
1255         res = 0;
1256     *b1 = !*b1;
1257     *b2 = ~*b2;
1258     *b3 = !*b3;
1259     return res;
1260 }
1261
1262 struct BoolStruct
1263 {
1264     int i;
1265     char b1;
1266     short b2; /* variant_bool */
1267     int b3;
1268 };
1269
1270 STDCALL int 
1271 marshal_test_bool_struct(struct BoolStruct *s)
1272 {
1273     int res = 1;
1274     if (s->b1 != 0 && s->b1 != 1)
1275         return 1;
1276     if (s->b2 != 0 && s->b2 != -1)
1277         return 1;
1278     if (s->b3 != 0 && s->b3 != 1)
1279         return 1;
1280     if (s->i == ((s->b1 << 2) | (-s->b2 << 1) | s->b3))
1281         res = 0;
1282     s->b1 = !s->b1;
1283     s->b2 = ~s->b2;
1284     s->b3 = !s->b3;
1285     return res;
1286 }
1287
1288 STDCALL void
1289 mono_test_last_error (int err)
1290 {
1291 #ifdef WIN32
1292         SetLastError (err);
1293 #else
1294         errno = err;
1295 #endif
1296 }
1297
1298 STDCALL int
1299 mono_test_asany (void *ptr, int what)
1300 {
1301         switch (what) {
1302         case 1:
1303                 return (*(int*)ptr == 5) ? 0 : 1;
1304         case 2:
1305                 return strcmp (ptr, "ABC") == 0 ? 0 : 1;
1306         case 3: {
1307                 simplestruct2 ss = *(simplestruct2*)ptr;
1308
1309                 if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
1310             !strcmp (ss.d, "TEST") && 
1311             ss.e == 99 && ss.f == 1.5 && ss.g == 42 && ss.h == (guint64)123)
1312                         return 0;
1313                 else
1314                         return 1;
1315         }
1316         case 4: {
1317                 GError *error = NULL;
1318                 char *s;
1319
1320                 s = g_utf16_to_utf8 (ptr, -1, NULL, NULL, &error);
1321                 if (!strcmp (s, "ABC")) {
1322                         g_free (s);
1323                         return 0;
1324                 }
1325                 else {
1326                         g_free (s);
1327                         return 1;
1328                 }
1329         }
1330         default:
1331                 g_assert_not_reached ();
1332         }
1333
1334         return 1;
1335 }
1336
1337 typedef struct
1338 {
1339         int i;
1340         int j;
1341         int k;
1342         char *s;
1343 } AsAnyStruct;
1344
1345 STDCALL int
1346 mono_test_marshal_asany_inout (void* ptr)
1347 {
1348         AsAnyStruct* asAny = ptr;
1349         int res = asAny->i + asAny->j + asAny->k;
1350
1351         asAny->i = 10;
1352         asAny->j = 20;
1353         asAny->k = 30;
1354         asAny->s = 0;
1355
1356         return res;
1357 }
1358
1359 /*
1360  * AMD64 marshalling tests.
1361  */
1362
1363 typedef struct amd64_struct1 {
1364         int i;
1365         int j;
1366         int k;
1367         int l;
1368 } amd64_struct1;
1369
1370 STDCALL amd64_struct1
1371 mono_test_marshal_amd64_pass_return_struct1 (amd64_struct1 s)
1372 {
1373         s.i ++;
1374         s.j ++;
1375         s.k ++;
1376         s.l ++;
1377
1378         return s;
1379 }
1380
1381 typedef struct amd64_struct2 {
1382         int i;
1383         int j;
1384 } amd64_struct2;
1385
1386 STDCALL amd64_struct2
1387 mono_test_marshal_amd64_pass_return_struct2 (amd64_struct2 s)
1388 {
1389         s.i ++;
1390         s.j ++;
1391
1392         return s;
1393 }
1394
1395 typedef struct amd64_struct3 {
1396         int i;
1397 } amd64_struct3;
1398
1399 STDCALL amd64_struct3
1400 mono_test_marshal_amd64_pass_return_struct3 (amd64_struct3 s)
1401 {
1402         s.i ++;
1403
1404         return s;
1405 }
1406
1407 typedef struct amd64_struct4 {
1408         double d1, d2;
1409 } amd64_struct4;
1410
1411 STDCALL amd64_struct4
1412 mono_test_marshal_amd64_pass_return_struct4 (amd64_struct4 s)
1413 {
1414         s.d1 ++;
1415         s.d2 ++;
1416
1417         return s;
1418 }
1419
1420 /*
1421  * IA64 marshalling tests.
1422  */
1423 typedef struct test_struct5 {
1424         float d1, d2;
1425 } test_struct5;
1426
1427 STDCALL test_struct5
1428 mono_test_marshal_ia64_pass_return_struct5 (double d1, double d2, test_struct5 s, double d3, double d4)
1429 {
1430         s.d1 += d1 + d2;
1431         s.d2 += d3 + d4;
1432
1433         return s;
1434 }
1435
1436 typedef struct test_struct6 {
1437         double d1, d2;
1438 } test_struct6;
1439
1440 STDCALL test_struct6
1441 mono_test_marshal_ia64_pass_return_struct6 (double d1, double d2, test_struct6 s, double d3, double d4)
1442 {
1443         s.d1 += d1 + d2;
1444         s.d2 += d3 + d4;
1445
1446         return s;
1447 }
1448
1449 static guint32 custom_res [2];
1450
1451 STDCALL void*
1452 mono_test_marshal_pass_return_custom (int i, guint32 *ptr, int j)
1453 {
1454         /* ptr will be freed by CleanupNative, so make a copy */
1455         custom_res [0] = 0; /* not allocated by AllocHGlobal */
1456         custom_res [1] = ptr [1];
1457
1458         return &custom_res;
1459 }
1460
1461 STDCALL int
1462 mono_test_marshal_pass_out_custom (int i, guint32 **ptr, int j)
1463 {
1464         custom_res [0] = 0;
1465         custom_res [1] = i + j + 10;
1466
1467         *ptr = custom_res;
1468
1469         return 0;
1470 }
1471
1472 STDCALL int
1473 mono_test_marshal_pass_inout_custom (int i, guint32 *ptr, int j)
1474 {
1475         ptr [0] = 0;
1476         ptr [1] = i + ptr [1] + j;
1477
1478         return 0;
1479 }
1480
1481 STDCALL int
1482 mono_test_marshal_pass_out_byval_custom (int i, guint32 *ptr, int j)
1483 {
1484         return ptr == NULL ? 0 : 1;
1485 }
1486
1487 STDCALL int
1488 mono_test_marshal_pass_byref_custom (int i, guint32 **ptr, int j)
1489 {
1490         (*ptr)[1] += i + j;
1491
1492         return 0;
1493 }
1494
1495 STDCALL void*
1496 mono_test_marshal_pass_return_custom2 (int i, guint32 *ptr, int j)
1497 {
1498         g_assert_not_reached ();
1499
1500         return NULL;
1501 }
1502
1503 STDCALL void*
1504 mono_test_marshal_pass_return_custom_null (int i, guint32 *ptr, int j)
1505 {
1506         g_assert (ptr == NULL);
1507
1508         return NULL;
1509 }
1510
1511 typedef void *(STDCALL *PassReturnPtrDelegate) (void *ptr);
1512
1513 STDCALL int
1514 mono_test_marshal_pass_return_custom_in_delegate (PassReturnPtrDelegate del)
1515 {
1516         guint32 buf [2];
1517         guint32 res;
1518         guint32 *ptr;
1519
1520         buf [0] = 0;
1521         buf [1] = 10;
1522
1523         ptr = del (&buf);
1524
1525         res = ptr [1];
1526
1527 #ifdef WIN32
1528         /* FIXME: Freed with FreeHGlobal */
1529 #else
1530         g_free (ptr);
1531 #endif
1532
1533         return res;
1534 }
1535
1536 STDCALL int
1537 mono_test_marshal_pass_return_custom_null_in_delegate (PassReturnPtrDelegate del)
1538 {
1539         void *ptr = del (NULL);
1540
1541         return (ptr == NULL) ? 15 : 0;
1542 }
1543
1544 typedef int (STDCALL *ReturnEnumDelegate) (int e);
1545
1546 STDCALL int
1547 mono_test_marshal_return_enum_delegate (ReturnEnumDelegate func)
1548 {
1549         return func (1);
1550 }
1551
1552 typedef struct {
1553         int a, b, c;
1554         gint64 d;
1555 } BlittableStruct;
1556         
1557 typedef BlittableStruct (STDCALL *SimpleDelegate10) (BlittableStruct ss);
1558
1559 STDCALL int
1560 mono_test_marshal_blittable_struct_delegate (SimpleDelegate10 delegate)
1561 {
1562         BlittableStruct ss, res;
1563
1564         ss.a = 1;
1565         ss.b = 2;
1566         ss.c = 3;
1567         ss.d = 55;
1568
1569         res = delegate (ss);
1570         if (! ((res.a == -1) && (res.b == -2) && (res.c == -3) && (res.d == -55)))
1571                 return 1;
1572
1573         return 0;
1574 }
1575
1576 STDCALL int
1577 mono_test_stdcall_name_mangling (int a, int b, int c)
1578 {
1579         return a + b + c;
1580 }
1581
1582 /*
1583  * PASSING AND RETURNING SMALL STRUCTURES FROM DELEGATES TESTS
1584  */
1585
1586 typedef struct {
1587         int i;
1588 } SmallStruct1;
1589         
1590 typedef SmallStruct1 (STDCALL *SmallStructDelegate1) (SmallStruct1 ss);
1591
1592 STDCALL int
1593 mono_test_marshal_small_struct_delegate1 (SmallStructDelegate1 delegate)
1594 {
1595         SmallStruct1 ss, res;
1596
1597         ss.i = 1;
1598
1599         res = delegate (ss);
1600         if (! (res.i == -1))
1601                 return 1;
1602
1603         return 0;
1604 }
1605
1606 typedef struct {
1607         gint16 i, j;
1608 } SmallStruct2;
1609         
1610 typedef SmallStruct2 (STDCALL *SmallStructDelegate2) (SmallStruct2 ss);
1611
1612 STDCALL int
1613 mono_test_marshal_small_struct_delegate2 (SmallStructDelegate2 delegate)
1614 {
1615         SmallStruct2 ss, res;
1616
1617         ss.i = 2;
1618         ss.j = 3;
1619
1620         res = delegate (ss);
1621         if (! ((res.i == -2) && (res.j == -3)))
1622                 return 1;
1623
1624         return 0;
1625 }
1626
1627 typedef struct {
1628         gint16 i;
1629         gint8 j;
1630 } SmallStruct3;
1631         
1632 typedef SmallStruct3 (STDCALL *SmallStructDelegate3) (SmallStruct3 ss);
1633
1634 STDCALL int
1635 mono_test_marshal_small_struct_delegate3 (SmallStructDelegate3 delegate)
1636 {
1637         SmallStruct3 ss, res;
1638
1639         ss.i = 1;
1640         ss.j = 2;
1641
1642         res = delegate (ss);
1643         if (! ((res.i == -1) && (res.j == -2)))
1644                 return 1;
1645
1646         return 0;
1647 }
1648
1649 typedef struct {
1650         gint16 i;
1651 } SmallStruct4;
1652         
1653 typedef SmallStruct4 (STDCALL *SmallStructDelegate4) (SmallStruct4 ss);
1654
1655 STDCALL int
1656 mono_test_marshal_small_struct_delegate4 (SmallStructDelegate4 delegate)
1657 {
1658         SmallStruct4 ss, res;
1659
1660         ss.i = 1;
1661
1662         res = delegate (ss);
1663         if (! (res.i == -1))
1664                 return 1;
1665
1666         return 0;
1667 }
1668
1669 typedef struct {
1670         gint64 i;
1671 } SmallStruct5;
1672         
1673 typedef SmallStruct5 (STDCALL *SmallStructDelegate5) (SmallStruct5 ss);
1674
1675 STDCALL int
1676 mono_test_marshal_small_struct_delegate5 (SmallStructDelegate5 delegate)
1677 {
1678         SmallStruct5 ss, res;
1679
1680         ss.i = 5;
1681
1682         res = delegate (ss);
1683         if (! (res.i == -5))
1684                 return 1;
1685
1686         return 0;
1687 }
1688
1689 typedef struct {
1690         int i, j;
1691 } SmallStruct6;
1692         
1693 typedef SmallStruct6 (STDCALL *SmallStructDelegate6) (SmallStruct6 ss);
1694
1695 STDCALL int
1696 mono_test_marshal_small_struct_delegate6 (SmallStructDelegate6 delegate)
1697 {
1698         SmallStruct6 ss, res;
1699
1700         ss.i = 1;
1701         ss.j = 2;
1702
1703         res = delegate (ss);
1704         if (! ((res.i == -1) && (res.j == -2)))
1705                 return 1;
1706
1707         return 0;
1708 }
1709
1710 typedef struct {
1711         int i;
1712         gint16 j;
1713 } SmallStruct7;
1714         
1715 typedef SmallStruct7 (STDCALL *SmallStructDelegate7) (SmallStruct7 ss);
1716
1717 STDCALL int
1718 mono_test_marshal_small_struct_delegate7 (SmallStructDelegate7 delegate)
1719 {
1720         SmallStruct7 ss, res;
1721
1722         ss.i = 1;
1723         ss.j = 2;
1724
1725         res = delegate (ss);
1726         if (! ((res.i == -1) && (res.j == -2)))
1727                 return 1;
1728
1729         return 0;
1730 }
1731
1732 typedef struct {
1733         float i;
1734 } SmallStruct8;
1735         
1736 typedef SmallStruct8 (STDCALL *SmallStructDelegate8) (SmallStruct8 ss);
1737
1738 STDCALL int
1739 mono_test_marshal_small_struct_delegate8 (SmallStructDelegate8 delegate)
1740 {
1741         SmallStruct8 ss, res;
1742
1743         ss.i = 1.0;
1744
1745         res = delegate (ss);
1746         if (! ((res.i == -1.0)))
1747                 return 1;
1748
1749         return 0;
1750 }
1751
1752 typedef struct {
1753         double i;
1754 } SmallStruct9;
1755         
1756 typedef SmallStruct9 (STDCALL *SmallStructDelegate9) (SmallStruct9 ss);
1757
1758 STDCALL int
1759 mono_test_marshal_small_struct_delegate9 (SmallStructDelegate9 delegate)
1760 {
1761         SmallStruct9 ss, res;
1762
1763         ss.i = 1.0;
1764
1765         res = delegate (ss);
1766         if (! ((res.i == -1.0)))
1767                 return 1;
1768
1769         return 0;
1770 }
1771
1772 typedef struct {
1773         float i, j;
1774 } SmallStruct10;
1775         
1776 typedef SmallStruct10 (STDCALL *SmallStructDelegate10) (SmallStruct10 ss);
1777
1778 STDCALL int
1779 mono_test_marshal_small_struct_delegate10 (SmallStructDelegate10 delegate)
1780 {
1781         SmallStruct10 ss, res;
1782
1783         ss.i = 1.0;
1784         ss.j = 2.0;
1785
1786         res = delegate (ss);
1787         if (! ((res.i == -1.0) && (res.j == -2.0)))
1788                 return 1;
1789
1790         return 0;
1791 }
1792
1793 typedef struct {
1794         float i;
1795         int j;
1796 } SmallStruct11;
1797         
1798 typedef SmallStruct11 (STDCALL *SmallStructDelegate11) (SmallStruct11 ss);
1799
1800 STDCALL int
1801 mono_test_marshal_small_struct_delegate11 (SmallStructDelegate11 delegate)
1802 {
1803         SmallStruct11 ss, res;
1804
1805         ss.i = 1.0;
1806         ss.j = 2;
1807
1808         res = delegate (ss);
1809         if (! ((res.i == -1.0) && (res.j == -2)))
1810                 return 1;
1811
1812         return 0;
1813 }
1814
1815 typedef int (STDCALL *ArrayDelegate) (int i, char *j, void *arr);
1816
1817 STDCALL int
1818 mono_test_marshal_array_delegate (void *arr, int len, ArrayDelegate del)
1819 {
1820         return del (len, NULL, arr);
1821 }
1822
1823 STDCALL int
1824 mono_test_marshal_out_array_delegate (int *arr, int len, ArrayDelegate del)
1825 {
1826         del (len, NULL, arr);
1827
1828         if ((arr [0] != 1) || (arr [1] != 2))
1829                 return 1;
1830         else
1831                 return 0;
1832 }
1833
1834 STDCALL int
1835 mono_test_marshal_out_string_array_delegate (char **arr, int len, ArrayDelegate del)
1836 {
1837         del (len, NULL, arr);
1838
1839         if (!strcmp (arr [0], "ABC") && !strcmp (arr [1], "DEF"))
1840                 return 0;
1841         else
1842                 return 1;
1843 }
1844
1845 typedef int (*CdeclDelegate) (int i, int j);
1846
1847 STDCALL int
1848 mono_test_marshal_cdecl_delegate (CdeclDelegate del)
1849 {
1850         int i;
1851
1852         for (i = 0; i < 1000; ++i)
1853                 del (1, 2);
1854
1855         return 0;
1856 }
1857
1858 typedef char** (*ReturnStringArrayDelegate) (int i);
1859
1860 STDCALL int
1861 mono_test_marshal_return_string_array_delegate (ReturnStringArrayDelegate d)
1862 {
1863         char **arr = d (2);
1864         int res;
1865
1866         if (arr == NULL)
1867                 return 3;
1868
1869         if (strcmp (arr [0], "ABC") || strcmp (arr [1], "DEF"))
1870                 res = 1;
1871         else
1872                 res = 0;
1873
1874         marshal_free (arr);
1875
1876         return res;
1877 }
1878
1879 STDCALL int
1880 add_delegate (int i, int j)
1881 {
1882         return i + j;
1883 }
1884
1885 STDCALL gpointer
1886 mono_test_marshal_return_fnptr (void)
1887 {
1888         return &add_delegate;
1889 }
1890
1891 /*
1892  * COM INTEROP TESTS
1893  */
1894
1895 #ifdef WIN32
1896
1897 STDCALL int
1898 mono_test_marshal_bstr_in(BSTR bstr)
1899 {
1900         if (!wcscmp(bstr, L"mono_test_marshal_bstr_in"))
1901                 return 0;
1902         return 1;
1903 }
1904
1905 STDCALL int
1906 mono_test_marshal_bstr_out(BSTR* bstr)
1907 {
1908         *bstr = SysAllocString(L"mono_test_marshal_bstr_out");
1909         return 0;
1910 }
1911
1912 STDCALL int
1913 mono_test_marshal_bstr_in_null(BSTR bstr)
1914 {
1915         if (!bstr)
1916                 return 0;
1917         return 1;
1918 }
1919
1920 STDCALL int
1921 mono_test_marshal_bstr_out_null(BSTR* bstr)
1922 {
1923         *bstr = NULL;
1924         return 0;
1925 }
1926
1927 STDCALL int
1928 mono_test_marshal_variant_in_sbyte(VARIANT variant)
1929 {
1930         if (variant.vt == VT_I1 && variant.cVal == 100)
1931                 return 0;
1932         return 1;
1933 }
1934
1935 STDCALL int
1936 mono_test_marshal_variant_in_byte(VARIANT variant)
1937 {
1938         if (variant.vt == VT_UI1 && variant.bVal == 100)
1939                 return 0;
1940         return 1;
1941 }
1942
1943 STDCALL int
1944 mono_test_marshal_variant_in_short(VARIANT variant)
1945 {
1946         if (variant.vt == VT_I2 && variant.iVal == 314)
1947                 return 0;
1948         return 1;
1949 }
1950
1951 STDCALL int
1952 mono_test_marshal_variant_in_ushort(VARIANT variant)
1953 {
1954         if (variant.vt == VT_UI2 && variant.uiVal == 314)
1955                 return 0;
1956         return 1;
1957 }
1958
1959 STDCALL int
1960 mono_test_marshal_variant_in_int(VARIANT variant)
1961 {
1962         if (variant.vt == VT_I4 && variant.lVal == 314)
1963                 return 0;
1964         return 1;
1965 }
1966
1967 STDCALL int
1968 mono_test_marshal_variant_in_uint(VARIANT variant)
1969 {
1970         if (variant.vt == VT_UI4 && variant.ulVal == 314)
1971                 return 0;
1972         return 1;
1973 }
1974
1975 STDCALL int
1976 mono_test_marshal_variant_in_long(VARIANT variant)
1977 {
1978         if (variant.vt == VT_I8 && variant.llVal == 314)
1979                 return 0;
1980         return 1;
1981 }
1982
1983 STDCALL int
1984 mono_test_marshal_variant_in_ulong(VARIANT variant)
1985 {
1986         if (variant.vt == VT_UI8 && variant.ullVal == 314)
1987                 return 0;
1988         return 1;
1989 }
1990
1991 STDCALL int
1992 mono_test_marshal_variant_in_float(VARIANT variant)
1993 {
1994         if (variant.vt == VT_R4 && (variant.fltVal - 3.14)/3.14 < .001)
1995                 return 0;
1996         return 1;
1997 }
1998
1999 STDCALL int
2000 mono_test_marshal_variant_in_double(VARIANT variant)
2001 {
2002         if (variant.vt == VT_R8 && (variant.dblVal - 3.14)/3.14 < .001)
2003                 return 0;
2004         return 1;
2005 }
2006
2007 STDCALL int
2008 mono_test_marshal_variant_in_bstr(VARIANT variant)
2009 {
2010         if (variant.vt == VT_BSTR && !wcscmp(variant.bstrVal, L"PI"))
2011                 return 0;
2012         return 1;
2013 }
2014
2015 STDCALL int
2016 mono_test_marshal_variant_in_bool_true (VARIANT variant)
2017 {
2018         if (variant.vt == VT_BOOL && variant.ullVal == VARIANT_TRUE)
2019                 return 0;
2020         return 1;
2021 }
2022
2023 STDCALL int
2024 mono_test_marshal_variant_in_bool_false (VARIANT variant)
2025 {
2026         if (variant.vt == VT_BOOL && variant.ullVal == VARIANT_FALSE)
2027                 return 0;
2028         return 1;
2029 }
2030
2031 STDCALL int
2032 mono_test_marshal_variant_out_sbyte(VARIANT* variant)
2033 {
2034         variant->vt = VT_I1;
2035         variant->cVal = 100;
2036
2037         return 0;
2038 }
2039
2040 STDCALL int
2041 mono_test_marshal_variant_out_byte(VARIANT* variant)
2042 {       
2043         variant->vt = VT_UI1;
2044         variant->bVal = 100;
2045
2046         return 0;
2047 }
2048
2049 STDCALL int
2050 mono_test_marshal_variant_out_short(VARIANT* variant)
2051 {
2052         variant->vt = VT_I2;
2053         variant->iVal = 314;
2054
2055         return 0;
2056 }
2057
2058 STDCALL int
2059 mono_test_marshal_variant_out_ushort(VARIANT* variant)
2060 {
2061         variant->vt = VT_UI2;
2062         variant->uiVal = 314;
2063
2064         return 0;
2065 }
2066
2067 STDCALL int
2068 mono_test_marshal_variant_out_int(VARIANT* variant)
2069 {
2070         variant->vt = VT_I4;
2071         variant->lVal = 314;
2072
2073         return 0;
2074 }
2075
2076 STDCALL int
2077 mono_test_marshal_variant_out_uint(VARIANT* variant)
2078 {
2079         variant->vt = VT_UI4;
2080         variant->ulVal = 314;
2081
2082         return 0;
2083 }
2084
2085 STDCALL int
2086 mono_test_marshal_variant_out_long(VARIANT* variant)
2087 {
2088         variant->vt = VT_I8;
2089         variant->llVal = 314;
2090
2091         return 0;
2092 }
2093
2094 STDCALL int
2095 mono_test_marshal_variant_out_ulong(VARIANT* variant)
2096 {
2097         variant->vt = VT_UI8;
2098         variant->ullVal = 314;
2099
2100         return 0;
2101 }
2102
2103 STDCALL int
2104 mono_test_marshal_variant_out_float(VARIANT* variant)
2105 {
2106         variant->vt = VT_R4;
2107         variant->fltVal = 3.14;
2108
2109         return 0;
2110 }
2111
2112 STDCALL int
2113 mono_test_marshal_variant_out_double(VARIANT* variant)
2114 {
2115         variant->vt = VT_R8;
2116         variant->dblVal = 3.14;
2117
2118         return 0;
2119 }
2120
2121 STDCALL int
2122 mono_test_marshal_variant_out_bstr(VARIANT* variant)
2123 {
2124         variant->vt = VT_BSTR;
2125         variant->bstrVal = SysAllocString(L"PI");
2126
2127         return 0;
2128 }
2129
2130 STDCALL int
2131 mono_test_marshal_variant_out_bool_true (VARIANT* variant)
2132 {
2133         variant->vt = VT_BOOL;
2134         variant->bstrVal = VARIANT_TRUE;
2135
2136         return 0;
2137 }
2138
2139 STDCALL int
2140 mono_test_marshal_variant_out_bool_false (VARIANT* variant)
2141 {
2142         variant->vt = VT_BOOL;
2143         variant->bstrVal = VARIANT_FALSE;
2144
2145         return 0;
2146 }
2147
2148 #ifdef _MSC_VER
2149 #define COM_STDCALL __stdcall
2150 #else
2151 #define COM_STDCALL __attribute__((stdcall))
2152 #endif
2153
2154 typedef struct MonoComObject MonoComObject;
2155
2156 typedef struct
2157 {
2158         int (COM_STDCALL *QueryInterface)(MonoComObject* pUnk, gpointer riid, gpointer* ppv);
2159         int (COM_STDCALL *AddRef)(MonoComObject* pUnk);
2160         int (COM_STDCALL *Release)(MonoComObject* pUnk);
2161         int (COM_STDCALL *Add)(MonoComObject* pUnk, int a, int b, int* c);
2162         int (COM_STDCALL *Subtract)(MonoComObject* pUnk, int a, int b, int* c);
2163         int (COM_STDCALL *Same)(MonoComObject* pUnk, MonoComObject* *pOut);
2164         int (COM_STDCALL *Different)(MonoComObject* pUnk, MonoComObject* *pOut);
2165 } MonoIUnknown;
2166
2167 struct MonoComObject
2168 {
2169         MonoIUnknown* vtbl;
2170         int m_ref;
2171 };
2172
2173 DEFINE_GUID(IID_IMath, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);
2174 DEFINE_GUID(IID_IMonoUnknown, 0, 0, 0, 0xC0, 0, 0, 0, 0, 0, 0, 0x46);
2175 DEFINE_GUID(IID_IMonoDispatch, 0x00020400, 0, 0, 0xC0, 0, 0, 0, 0, 0, 0, 0x46);
2176
2177 int COM_STDCALL MonoQueryInterface(MonoComObject* pUnk, gpointer riid, gpointer* ppv)
2178 {
2179         *ppv = NULL;
2180         if (!memcmp(riid, &IID_IMonoUnknown, sizeof(GUID))) {
2181                 *ppv = pUnk;
2182                 return S_OK;
2183         }
2184         else if (!memcmp(riid, &IID_IMath, sizeof(GUID))) {
2185                 *ppv = pUnk;
2186                 return S_OK;
2187         }
2188         else if (!memcmp(riid, &IID_IMonoDispatch, sizeof(GUID))) {
2189                 *ppv = pUnk;
2190                 return S_OK;
2191         }
2192         return E_NOINTERFACE;
2193 }
2194
2195 int COM_STDCALL MonoAddRef(MonoComObject* pUnk)
2196 {
2197         return ++(pUnk->m_ref);
2198 }
2199
2200 int COM_STDCALL MonoRelease(MonoComObject* pUnk)
2201 {
2202         return --(pUnk->m_ref);
2203 }
2204
2205 int COM_STDCALL Add(MonoComObject* pUnk, int a, int b, int* c)
2206 {
2207         *c = a + b;
2208         return 0;
2209 }
2210
2211 int COM_STDCALL Subtract(MonoComObject* pUnk, int a, int b, int* c)
2212 {
2213         *c = a - b;
2214         return 0;
2215 }
2216
2217 static void create_com_object (MonoComObject** pOut);
2218 static MonoComObject* same_com_object = NULL;
2219
2220 int COM_STDCALL Same(MonoComObject* pUnk, MonoComObject** pOut)
2221 {
2222         if (!same_com_object)
2223                 create_com_object (&same_com_object);
2224         *pOut = same_com_object;
2225         return 0;
2226 }
2227
2228 int COM_STDCALL Different(MonoComObject* pUnk, MonoComObject** pOut)
2229 {
2230         create_com_object (pOut);
2231         return 0;
2232 }
2233
2234 static void create_com_object (MonoComObject** pOut)
2235 {
2236         *pOut = g_new0 (MonoComObject, 1);
2237         (*pOut)->vtbl = g_new0 (MonoIUnknown, 1);
2238
2239         (*pOut)->m_ref = 1;
2240         (*pOut)->vtbl->QueryInterface = MonoQueryInterface;
2241         (*pOut)->vtbl->AddRef = MonoAddRef;
2242         (*pOut)->vtbl->Release = MonoRelease;
2243         (*pOut)->vtbl->Add = Add;
2244         (*pOut)->vtbl->Subtract = Subtract;
2245         (*pOut)->vtbl->Same = Same;
2246         (*pOut)->vtbl->Different = Different;
2247 }
2248
2249 STDCALL int
2250 mono_test_marshal_com_object_create(MonoComObject* *pUnk)
2251 {
2252         create_com_object (pUnk);
2253
2254         return 0;
2255 }
2256
2257 STDCALL int
2258 mono_test_marshal_com_object_destroy(MonoComObject *pUnk)
2259 {
2260         int ref = --(pUnk->m_ref);
2261         g_free(pUnk->vtbl);
2262         g_free(pUnk);
2263
2264         return ref;
2265 }
2266
2267 STDCALL int
2268 mono_test_marshal_com_object_ref_count(MonoComObject *pUnk)
2269 {
2270         return pUnk->m_ref;
2271 }
2272
2273 #endif //NOT_YET