2007-01-01 Miguel de Icaza <miguel@novell.com>
[mono.git] / mono / tests / libtest.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <glib.h>
5 #include <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 typedef struct {
989         char a[8];
990         int  flag;
991 } ByValStrStruct_Unicode;
992
993 STDCALL int
994 mono_test_byvalstr_check_unicode (ByValStrStruct_Unicode *ref, int test)
995 {
996         if (ref->flag != 0x1234abcd){
997                 printf ("overwritten data");
998                 return 1;
999         }
1000             
1001         if (test == 1 || test == 3){
1002                 if (ref->a [0] != '1' ||
1003                     ref->a [1] != 0   ||
1004                     ref->a [2] != '2' ||
1005                     ref->a [3] != 0 ||
1006                     ref->a [4] != '3' ||
1007                     ref->a [5] != 0)
1008                         return 1;
1009                 return 0;
1010         }
1011         if (test == 2){
1012                 if (ref->a [0] != '1' ||
1013                     ref->a [1] != 0   ||
1014                     ref->a [2] != '2' ||
1015                     ref->a [3] != 0)
1016                         return 1;
1017                 return 0;
1018         }
1019         return 10;
1020 }
1021
1022 STDCALL int
1023 NameManglingAnsi (char *data)
1024 {
1025         return data [0] + data [1] + data [2];
1026 }
1027
1028 STDCALL int
1029 NameManglingAnsiA (char *data)
1030 {
1031         g_assert_not_reached ();
1032 }
1033
1034 STDCALL int
1035 NameManglingAnsiW (char *data)
1036 {
1037         g_assert_not_reached ();
1038 }
1039
1040 STDCALL int
1041 NameManglingAnsi2A (char *data)
1042 {
1043         return data [0] + data [1] + data [2];
1044 }
1045
1046 STDCALL int
1047 NameManglingAnsi2W (char *data)
1048 {
1049         g_assert_not_reached ();
1050 }
1051
1052 STDCALL int
1053 NameManglingUnicode (char *data)
1054 {
1055         g_assert_not_reached ();
1056 }
1057
1058 STDCALL int
1059 NameManglingUnicodeW (gunichar2 *data)
1060 {
1061         return data [0] + data [1] + data [2];
1062 }
1063
1064 STDCALL int
1065 NameManglingUnicode2 (gunichar2 *data)
1066 {
1067         return data [0] + data [1] + data [2];
1068 }
1069
1070 STDCALL int
1071 NameManglingAutoW (char *data)
1072 {
1073 #ifdef WIN32
1074         return (data [0] + data [1] + data [2]) == 131 ? 0 : 1;
1075 #else
1076         g_assert_not_reached ();
1077 #endif
1078 }
1079
1080 STDCALL int
1081 NameManglingAuto (char *data)
1082 {
1083 #ifndef WIN32
1084         return (data [0] + data [1] + data [2]) == 198 ? 0 : 1;
1085 #else
1086         g_assert_not_reached ();
1087 #endif
1088 }
1089
1090 typedef int (STDCALL *intcharFunc)(const char*);
1091
1092 STDCALL void 
1093 callFunction (intcharFunc f)
1094 {
1095         f ("ABC");
1096 }
1097
1098 typedef struct {
1099         const char* str;
1100         int i;
1101 } SimpleObj;
1102
1103 STDCALL int
1104 class_marshal_test0 (SimpleObj *obj1)
1105 {
1106         // printf ("class_marshal_test0 %s %d\n", obj1->str, obj1->i);
1107
1108         if (strcmp(obj1->str, "T1"))
1109                 return -1;
1110         if (obj1->i != 4)
1111                 return -2;
1112
1113         return 0;
1114 }
1115
1116 STDCALL int
1117 class_marshal_test4 (SimpleObj *obj1)
1118 {
1119         if (obj1)
1120                 return -1;
1121
1122         return 0;
1123 }
1124
1125 STDCALL void
1126 class_marshal_test1 (SimpleObj **obj1)
1127 {
1128         SimpleObj *res = malloc (sizeof (SimpleObj));
1129
1130         res->str = g_strdup ("ABC");
1131         res->i = 5;
1132
1133         *obj1 = res;
1134 }
1135
1136 STDCALL int
1137 class_marshal_test2 (SimpleObj **obj1)
1138 {
1139         // printf ("class_marshal_test2 %s %d\n", (*obj1)->str, (*obj1)->i);
1140
1141         if (strcmp((*obj1)->str, "ABC"))
1142                 return -1;
1143         if ((*obj1)->i != 5)
1144                 return -2;
1145
1146         return 0;
1147 }
1148
1149 STDCALL int
1150 string_marshal_test0 (char *str)
1151 {
1152         if (strcmp (str, "TEST0"))
1153                 return -1;
1154
1155         return 0;
1156 }
1157
1158 STDCALL void
1159 string_marshal_test1 (const char **str)
1160 {
1161         *str = "TEST1";
1162 }
1163
1164 STDCALL int
1165 string_marshal_test2 (char **str)
1166 {
1167         // printf ("string_marshal_test2 %s\n", *str);
1168
1169         if (strcmp (*str, "TEST1"))
1170                 return -1;
1171
1172         return 0;
1173 }
1174
1175 STDCALL int
1176 string_marshal_test3 (char *str)
1177 {
1178         if (str)
1179                 return -1;
1180
1181         return 0;
1182 }
1183
1184 typedef struct {
1185         int a;
1186         int b;
1187 } BlittableClass;
1188
1189 STDCALL BlittableClass* 
1190 TestBlittableClass (BlittableClass *vl)
1191 {
1192         BlittableClass *res;
1193
1194         // printf ("TestBlittableClass %d %d\n", vl->a, vl->b);
1195
1196         if (vl) {
1197                 vl->a++;
1198                 vl->b++;
1199
1200                 res = g_new0 (BlittableClass, 1);
1201                 memcpy (res, vl, sizeof (BlittableClass));
1202         } else {
1203                 res = g_new0 (BlittableClass, 1);
1204                 res->a = 42;
1205                 res->b = 43;
1206         }
1207
1208         return res;
1209 }
1210
1211 typedef struct OSVERSIONINFO_STRUCT
1212
1213         int a; 
1214         int b; 
1215 } OSVERSIONINFO_STRUCT;
1216
1217 STDCALL int 
1218 MyGetVersionEx (OSVERSIONINFO_STRUCT *osvi)
1219 {
1220
1221         // printf ("GOT %d %d\n", osvi->a, osvi->b);
1222
1223         osvi->a += 1;
1224         osvi->b += 1;
1225
1226         return osvi->a + osvi->b;
1227 }
1228
1229 STDCALL int 
1230 BugGetVersionEx (int a, int b, int c, int d, int e, int f, int g, int h, OSVERSIONINFO_STRUCT *osvi)
1231 {
1232
1233         // printf ("GOT %d %d\n", osvi->a, osvi->b);
1234
1235         osvi->a += 1;
1236         osvi->b += 1;
1237
1238         return osvi->a + osvi->b;
1239 }
1240
1241 STDCALL int
1242 mono_test_marshal_point (point pt)
1243 {
1244         // printf("point %g %g\n", pt.x, pt.y);
1245         if (pt.x == 1.25 && pt.y == 3.5)
1246                 return 0;
1247
1248         return 1;
1249 }
1250
1251 typedef struct {
1252         int x;
1253         double y;
1254 } mixed_point;
1255
1256 STDCALL int
1257 mono_test_marshal_mixed_point (mixed_point pt)
1258 {
1259         // printf("mixed point %d %g\n", pt.x, pt.y);
1260         if (pt.x == 5 && pt.y == 6.75)
1261                 return 0;
1262
1263         return 1;
1264 }
1265
1266 STDCALL int
1267 mono_test_marshal_mixed_point_2 (mixed_point *pt)
1268 {
1269         if (pt->x != 5 || pt->y != 6.75)
1270                 return 1;
1271
1272         pt->x = 10;
1273         pt->y = 12.35;
1274
1275         return 0;
1276 }
1277
1278 STDCALL int 
1279 marshal_test_ref_bool(int i, char *b1, short *b2, int *b3)
1280 {
1281     int res = 1;
1282     if (*b1 != 0 && *b1 != 1)
1283         return 1;
1284     if (*b2 != 0 && *b2 != -1) /* variant_bool */
1285         return 1;
1286     if (*b3 != 0 && *b3 != 1)
1287         return 1;
1288     if (i == ((*b1 << 2) | (-*b2 << 1) | *b3))
1289         res = 0;
1290     *b1 = !*b1;
1291     *b2 = ~*b2;
1292     *b3 = !*b3;
1293     return res;
1294 }
1295
1296 struct BoolStruct
1297 {
1298     int i;
1299     char b1;
1300     short b2; /* variant_bool */
1301     int b3;
1302 };
1303
1304 STDCALL int 
1305 marshal_test_bool_struct(struct BoolStruct *s)
1306 {
1307     int res = 1;
1308     if (s->b1 != 0 && s->b1 != 1)
1309         return 1;
1310     if (s->b2 != 0 && s->b2 != -1)
1311         return 1;
1312     if (s->b3 != 0 && s->b3 != 1)
1313         return 1;
1314     if (s->i == ((s->b1 << 2) | (-s->b2 << 1) | s->b3))
1315         res = 0;
1316     s->b1 = !s->b1;
1317     s->b2 = ~s->b2;
1318     s->b3 = !s->b3;
1319     return res;
1320 }
1321
1322 STDCALL void
1323 mono_test_last_error (int err)
1324 {
1325 #ifdef WIN32
1326         SetLastError (err);
1327 #else
1328         errno = err;
1329 #endif
1330 }
1331
1332 STDCALL int
1333 mono_test_asany (void *ptr, int what)
1334 {
1335         switch (what) {
1336         case 1:
1337                 return (*(int*)ptr == 5) ? 0 : 1;
1338         case 2:
1339                 return strcmp (ptr, "ABC") == 0 ? 0 : 1;
1340         case 3: {
1341                 simplestruct2 ss = *(simplestruct2*)ptr;
1342
1343                 if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
1344             !strcmp (ss.d, "TEST") && 
1345             ss.e == 99 && ss.f == 1.5 && ss.g == 42 && ss.h == (guint64)123)
1346                         return 0;
1347                 else
1348                         return 1;
1349         }
1350         case 4: {
1351                 GError *error = NULL;
1352                 char *s;
1353
1354                 s = g_utf16_to_utf8 (ptr, -1, NULL, NULL, &error);
1355                 if (!strcmp (s, "ABC")) {
1356                         g_free (s);
1357                         return 0;
1358                 }
1359                 else {
1360                         g_free (s);
1361                         return 1;
1362                 }
1363         }
1364         default:
1365                 g_assert_not_reached ();
1366         }
1367
1368         return 1;
1369 }
1370
1371 typedef struct
1372 {
1373         int i;
1374         int j;
1375         int k;
1376         char *s;
1377 } AsAnyStruct;
1378
1379 STDCALL int
1380 mono_test_marshal_asany_inout (void* ptr)
1381 {
1382         AsAnyStruct* asAny = ptr;
1383         int res = asAny->i + asAny->j + asAny->k;
1384
1385         asAny->i = 10;
1386         asAny->j = 20;
1387         asAny->k = 30;
1388         asAny->s = 0;
1389
1390         return res;
1391 }
1392
1393 /*
1394  * AMD64 marshalling tests.
1395  */
1396
1397 typedef struct amd64_struct1 {
1398         int i;
1399         int j;
1400         int k;
1401         int l;
1402 } amd64_struct1;
1403
1404 STDCALL amd64_struct1
1405 mono_test_marshal_amd64_pass_return_struct1 (amd64_struct1 s)
1406 {
1407         s.i ++;
1408         s.j ++;
1409         s.k ++;
1410         s.l ++;
1411
1412         return s;
1413 }
1414
1415 typedef struct amd64_struct2 {
1416         int i;
1417         int j;
1418 } amd64_struct2;
1419
1420 STDCALL amd64_struct2
1421 mono_test_marshal_amd64_pass_return_struct2 (amd64_struct2 s)
1422 {
1423         s.i ++;
1424         s.j ++;
1425
1426         return s;
1427 }
1428
1429 typedef struct amd64_struct3 {
1430         int i;
1431 } amd64_struct3;
1432
1433 STDCALL amd64_struct3
1434 mono_test_marshal_amd64_pass_return_struct3 (amd64_struct3 s)
1435 {
1436         s.i ++;
1437
1438         return s;
1439 }
1440
1441 typedef struct amd64_struct4 {
1442         double d1, d2;
1443 } amd64_struct4;
1444
1445 STDCALL amd64_struct4
1446 mono_test_marshal_amd64_pass_return_struct4 (amd64_struct4 s)
1447 {
1448         s.d1 ++;
1449         s.d2 ++;
1450
1451         return s;
1452 }
1453
1454 /*
1455  * IA64 marshalling tests.
1456  */
1457 typedef struct test_struct5 {
1458         float d1, d2;
1459 } test_struct5;
1460
1461 STDCALL test_struct5
1462 mono_test_marshal_ia64_pass_return_struct5 (double d1, double d2, test_struct5 s, double d3, double d4)
1463 {
1464         s.d1 += d1 + d2;
1465         s.d2 += d3 + d4;
1466
1467         return s;
1468 }
1469
1470 typedef struct test_struct6 {
1471         double d1, d2;
1472 } test_struct6;
1473
1474 STDCALL test_struct6
1475 mono_test_marshal_ia64_pass_return_struct6 (double d1, double d2, test_struct6 s, double d3, double d4)
1476 {
1477         s.d1 += d1 + d2;
1478         s.d2 += d3 + d4;
1479
1480         return s;
1481 }
1482
1483 static guint32 custom_res [2];
1484
1485 STDCALL void*
1486 mono_test_marshal_pass_return_custom (int i, guint32 *ptr, int j)
1487 {
1488         /* ptr will be freed by CleanupNative, so make a copy */
1489         custom_res [0] = 0; /* not allocated by AllocHGlobal */
1490         custom_res [1] = ptr [1];
1491
1492         return &custom_res;
1493 }
1494
1495 STDCALL int
1496 mono_test_marshal_pass_out_custom (int i, guint32 **ptr, int j)
1497 {
1498         custom_res [0] = 0;
1499         custom_res [1] = i + j + 10;
1500
1501         *ptr = custom_res;
1502
1503         return 0;
1504 }
1505
1506 STDCALL int
1507 mono_test_marshal_pass_inout_custom (int i, guint32 *ptr, int j)
1508 {
1509         ptr [0] = 0;
1510         ptr [1] = i + ptr [1] + j;
1511
1512         return 0;
1513 }
1514
1515 STDCALL int
1516 mono_test_marshal_pass_out_byval_custom (int i, guint32 *ptr, int j)
1517 {
1518         return ptr == NULL ? 0 : 1;
1519 }
1520
1521 STDCALL int
1522 mono_test_marshal_pass_byref_custom (int i, guint32 **ptr, int j)
1523 {
1524         (*ptr)[1] += i + j;
1525
1526         return 0;
1527 }
1528
1529 STDCALL void*
1530 mono_test_marshal_pass_return_custom2 (int i, guint32 *ptr, int j)
1531 {
1532         g_assert_not_reached ();
1533
1534         return NULL;
1535 }
1536
1537 STDCALL void*
1538 mono_test_marshal_pass_return_custom_null (int i, guint32 *ptr, int j)
1539 {
1540         g_assert (ptr == NULL);
1541
1542         return NULL;
1543 }
1544
1545 typedef void *(STDCALL *PassReturnPtrDelegate) (void *ptr);
1546
1547 STDCALL int
1548 mono_test_marshal_pass_return_custom_in_delegate (PassReturnPtrDelegate del)
1549 {
1550         guint32 buf [2];
1551         guint32 res;
1552         guint32 *ptr;
1553
1554         buf [0] = 0;
1555         buf [1] = 10;
1556
1557         ptr = del (&buf);
1558
1559         res = ptr [1];
1560
1561 #ifdef WIN32
1562         /* FIXME: Freed with FreeHGlobal */
1563 #else
1564         g_free (ptr);
1565 #endif
1566
1567         return res;
1568 }
1569
1570 STDCALL int
1571 mono_test_marshal_pass_return_custom_null_in_delegate (PassReturnPtrDelegate del)
1572 {
1573         void *ptr = del (NULL);
1574
1575         return (ptr == NULL) ? 15 : 0;
1576 }
1577
1578 typedef int (STDCALL *ReturnEnumDelegate) (int e);
1579
1580 STDCALL int
1581 mono_test_marshal_return_enum_delegate (ReturnEnumDelegate func)
1582 {
1583         return func (1);
1584 }
1585
1586 typedef struct {
1587         int a, b, c;
1588         gint64 d;
1589 } BlittableStruct;
1590         
1591 typedef BlittableStruct (STDCALL *SimpleDelegate10) (BlittableStruct ss);
1592
1593 STDCALL int
1594 mono_test_marshal_blittable_struct_delegate (SimpleDelegate10 delegate)
1595 {
1596         BlittableStruct ss, res;
1597
1598         ss.a = 1;
1599         ss.b = 2;
1600         ss.c = 3;
1601         ss.d = 55;
1602
1603         res = delegate (ss);
1604         if (! ((res.a == -1) && (res.b == -2) && (res.c == -3) && (res.d == -55)))
1605                 return 1;
1606
1607         return 0;
1608 }
1609
1610 STDCALL int
1611 mono_test_stdcall_name_mangling (int a, int b, int c)
1612 {
1613         return a + b + c;
1614 }
1615
1616 /*
1617  * PASSING AND RETURNING SMALL STRUCTURES FROM DELEGATES TESTS
1618  */
1619
1620 typedef struct {
1621         int i;
1622 } SmallStruct1;
1623         
1624 typedef SmallStruct1 (STDCALL *SmallStructDelegate1) (SmallStruct1 ss);
1625
1626 STDCALL int
1627 mono_test_marshal_small_struct_delegate1 (SmallStructDelegate1 delegate)
1628 {
1629         SmallStruct1 ss, res;
1630
1631         ss.i = 1;
1632
1633         res = delegate (ss);
1634         if (! (res.i == -1))
1635                 return 1;
1636
1637         return 0;
1638 }
1639
1640 typedef struct {
1641         gint16 i, j;
1642 } SmallStruct2;
1643         
1644 typedef SmallStruct2 (STDCALL *SmallStructDelegate2) (SmallStruct2 ss);
1645
1646 STDCALL int
1647 mono_test_marshal_small_struct_delegate2 (SmallStructDelegate2 delegate)
1648 {
1649         SmallStruct2 ss, res;
1650
1651         ss.i = 2;
1652         ss.j = 3;
1653
1654         res = delegate (ss);
1655         if (! ((res.i == -2) && (res.j == -3)))
1656                 return 1;
1657
1658         return 0;
1659 }
1660
1661 typedef struct {
1662         gint16 i;
1663         gint8 j;
1664 } SmallStruct3;
1665         
1666 typedef SmallStruct3 (STDCALL *SmallStructDelegate3) (SmallStruct3 ss);
1667
1668 STDCALL int
1669 mono_test_marshal_small_struct_delegate3 (SmallStructDelegate3 delegate)
1670 {
1671         SmallStruct3 ss, res;
1672
1673         ss.i = 1;
1674         ss.j = 2;
1675
1676         res = delegate (ss);
1677         if (! ((res.i == -1) && (res.j == -2)))
1678                 return 1;
1679
1680         return 0;
1681 }
1682
1683 typedef struct {
1684         gint16 i;
1685 } SmallStruct4;
1686         
1687 typedef SmallStruct4 (STDCALL *SmallStructDelegate4) (SmallStruct4 ss);
1688
1689 STDCALL int
1690 mono_test_marshal_small_struct_delegate4 (SmallStructDelegate4 delegate)
1691 {
1692         SmallStruct4 ss, res;
1693
1694         ss.i = 1;
1695
1696         res = delegate (ss);
1697         if (! (res.i == -1))
1698                 return 1;
1699
1700         return 0;
1701 }
1702
1703 typedef struct {
1704         gint64 i;
1705 } SmallStruct5;
1706         
1707 typedef SmallStruct5 (STDCALL *SmallStructDelegate5) (SmallStruct5 ss);
1708
1709 STDCALL int
1710 mono_test_marshal_small_struct_delegate5 (SmallStructDelegate5 delegate)
1711 {
1712         SmallStruct5 ss, res;
1713
1714         ss.i = 5;
1715
1716         res = delegate (ss);
1717         if (! (res.i == -5))
1718                 return 1;
1719
1720         return 0;
1721 }
1722
1723 typedef struct {
1724         int i, j;
1725 } SmallStruct6;
1726         
1727 typedef SmallStruct6 (STDCALL *SmallStructDelegate6) (SmallStruct6 ss);
1728
1729 STDCALL int
1730 mono_test_marshal_small_struct_delegate6 (SmallStructDelegate6 delegate)
1731 {
1732         SmallStruct6 ss, res;
1733
1734         ss.i = 1;
1735         ss.j = 2;
1736
1737         res = delegate (ss);
1738         if (! ((res.i == -1) && (res.j == -2)))
1739                 return 1;
1740
1741         return 0;
1742 }
1743
1744 typedef struct {
1745         int i;
1746         gint16 j;
1747 } SmallStruct7;
1748         
1749 typedef SmallStruct7 (STDCALL *SmallStructDelegate7) (SmallStruct7 ss);
1750
1751 STDCALL int
1752 mono_test_marshal_small_struct_delegate7 (SmallStructDelegate7 delegate)
1753 {
1754         SmallStruct7 ss, res;
1755
1756         ss.i = 1;
1757         ss.j = 2;
1758
1759         res = delegate (ss);
1760         if (! ((res.i == -1) && (res.j == -2)))
1761                 return 1;
1762
1763         return 0;
1764 }
1765
1766 typedef struct {
1767         float i;
1768 } SmallStruct8;
1769         
1770 typedef SmallStruct8 (STDCALL *SmallStructDelegate8) (SmallStruct8 ss);
1771
1772 STDCALL int
1773 mono_test_marshal_small_struct_delegate8 (SmallStructDelegate8 delegate)
1774 {
1775         SmallStruct8 ss, res;
1776
1777         ss.i = 1.0;
1778
1779         res = delegate (ss);
1780         if (! ((res.i == -1.0)))
1781                 return 1;
1782
1783         return 0;
1784 }
1785
1786 typedef struct {
1787         double i;
1788 } SmallStruct9;
1789         
1790 typedef SmallStruct9 (STDCALL *SmallStructDelegate9) (SmallStruct9 ss);
1791
1792 STDCALL int
1793 mono_test_marshal_small_struct_delegate9 (SmallStructDelegate9 delegate)
1794 {
1795         SmallStruct9 ss, res;
1796
1797         ss.i = 1.0;
1798
1799         res = delegate (ss);
1800         if (! ((res.i == -1.0)))
1801                 return 1;
1802
1803         return 0;
1804 }
1805
1806 typedef struct {
1807         float i, j;
1808 } SmallStruct10;
1809         
1810 typedef SmallStruct10 (STDCALL *SmallStructDelegate10) (SmallStruct10 ss);
1811
1812 STDCALL int
1813 mono_test_marshal_small_struct_delegate10 (SmallStructDelegate10 delegate)
1814 {
1815         SmallStruct10 ss, res;
1816
1817         ss.i = 1.0;
1818         ss.j = 2.0;
1819
1820         res = delegate (ss);
1821         if (! ((res.i == -1.0) && (res.j == -2.0)))
1822                 return 1;
1823
1824         return 0;
1825 }
1826
1827 typedef struct {
1828         float i;
1829         int j;
1830 } SmallStruct11;
1831         
1832 typedef SmallStruct11 (STDCALL *SmallStructDelegate11) (SmallStruct11 ss);
1833
1834 STDCALL int
1835 mono_test_marshal_small_struct_delegate11 (SmallStructDelegate11 delegate)
1836 {
1837         SmallStruct11 ss, res;
1838
1839         ss.i = 1.0;
1840         ss.j = 2;
1841
1842         res = delegate (ss);
1843         if (! ((res.i == -1.0) && (res.j == -2)))
1844                 return 1;
1845
1846         return 0;
1847 }
1848
1849 typedef int (STDCALL *ArrayDelegate) (int i, char *j, void *arr);
1850
1851 STDCALL int
1852 mono_test_marshal_array_delegate (void *arr, int len, ArrayDelegate del)
1853 {
1854         return del (len, NULL, arr);
1855 }
1856
1857 STDCALL int
1858 mono_test_marshal_out_array_delegate (int *arr, int len, ArrayDelegate del)
1859 {
1860         del (len, NULL, arr);
1861
1862         if ((arr [0] != 1) || (arr [1] != 2))
1863                 return 1;
1864         else
1865                 return 0;
1866 }
1867
1868 STDCALL int
1869 mono_test_marshal_out_string_array_delegate (char **arr, int len, ArrayDelegate del)
1870 {
1871         del (len, NULL, arr);
1872
1873         if (!strcmp (arr [0], "ABC") && !strcmp (arr [1], "DEF"))
1874                 return 0;
1875         else
1876                 return 1;
1877 }
1878
1879 typedef int (*CdeclDelegate) (int i, int j);
1880
1881 STDCALL int
1882 mono_test_marshal_cdecl_delegate (CdeclDelegate del)
1883 {
1884         int i;
1885
1886         for (i = 0; i < 1000; ++i)
1887                 del (1, 2);
1888
1889         return 0;
1890 }
1891
1892 typedef char** (*ReturnStringArrayDelegate) (int i);
1893
1894 STDCALL int
1895 mono_test_marshal_return_string_array_delegate (ReturnStringArrayDelegate d)
1896 {
1897         char **arr = d (2);
1898         int res;
1899
1900         if (arr == NULL)
1901                 return 3;
1902
1903         if (strcmp (arr [0], "ABC") || strcmp (arr [1], "DEF"))
1904                 res = 1;
1905         else
1906                 res = 0;
1907
1908         marshal_free (arr);
1909
1910         return res;
1911 }
1912
1913 STDCALL int
1914 add_delegate (int i, int j)
1915 {
1916         return i + j;
1917 }
1918
1919 STDCALL gpointer
1920 mono_test_marshal_return_fnptr (void)
1921 {
1922         return &add_delegate;
1923 }
1924
1925 int mono_xr (int code)
1926 {
1927         printf ("codigo %x\n", code);
1928         return code + 1234;
1929 }
1930
1931 typedef struct {
1932         int   a;
1933         void *handle1;
1934         void *handle2;
1935         int   b;
1936 } HandleStructs;
1937
1938 int
1939 mono_safe_handle_struct_ref (HandleStructs *x)
1940 {
1941         printf ("Dingus Ref! \n");
1942         printf ("Values: %d %d %d %d\n", x->a, x->b, x->handle1, x->handle2);
1943         if (x->a != 1234)
1944                 return 1;
1945         if (x->b != 8743)
1946                 return 2;
1947
1948         if (x->handle1 != (void*) 0x7080feed)
1949                 return 3;
1950
1951         if (x->handle2 != (void*) 0x1234abcd)
1952                 return 4;
1953
1954         return 0xf00d;
1955 }
1956
1957 int
1958 mono_safe_handle_struct (HandleStructs x)
1959 {
1960         printf ("Dingus Standard! \n");
1961         printf ("Values: %d %d %d %d\n", x.a, x.b, x.handle1, x.handle2);
1962         if (x.a != 1234)
1963                 return 1;
1964         if (x.b != 8743)
1965                 return 2;
1966
1967         if (x.handle1 != (void*) 0x7080feed)
1968                 return 3;
1969
1970         if (x.handle2 != (void*) 0x1234abcd)
1971                 return 4;
1972         
1973         return 0xf00f;
1974 }
1975
1976 typedef struct {
1977         void *a;
1978 } TrivialHandle;
1979
1980 int
1981 mono_safe_handle_struct_simple (TrivialHandle x)
1982 {
1983         printf ("The value is %d\n", x.a);
1984         return ((int)x.a) * 2;
1985 }
1986
1987 int
1988 mono_safe_handle_return ()
1989 {
1990         return 0x1000f00d;
1991 }
1992
1993 void
1994 mono_safe_handle_ref (void **handle)
1995 {
1996         if (*handle != 0){
1997                 *handle = (void *) 0xbad;
1998                 return;
1999         }
2000
2001         *handle = (void *) 0x800d;
2002 }
2003 /*
2004  * COM INTEROP TESTS
2005  */
2006
2007 #ifdef WIN32
2008
2009 STDCALL int
2010 mono_test_marshal_bstr_in(BSTR bstr)
2011 {
2012         if (!wcscmp(bstr, L"mono_test_marshal_bstr_in"))
2013                 return 0;
2014         return 1;
2015 }
2016
2017 STDCALL int
2018 mono_test_marshal_bstr_out(BSTR* bstr)
2019 {
2020         *bstr = SysAllocString(L"mono_test_marshal_bstr_out");
2021         return 0;
2022 }
2023
2024 STDCALL int
2025 mono_test_marshal_bstr_in_null(BSTR bstr)
2026 {
2027         if (!bstr)
2028                 return 0;
2029         return 1;
2030 }
2031
2032 STDCALL int
2033 mono_test_marshal_bstr_out_null(BSTR* bstr)
2034 {
2035         *bstr = NULL;
2036         return 0;
2037 }
2038
2039 STDCALL int
2040 mono_test_marshal_variant_in_sbyte(VARIANT variant)
2041 {
2042         if (variant.vt == VT_I1 && variant.cVal == 100)
2043                 return 0;
2044         return 1;
2045 }
2046
2047 STDCALL int
2048 mono_test_marshal_variant_in_byte(VARIANT variant)
2049 {
2050         if (variant.vt == VT_UI1 && variant.bVal == 100)
2051                 return 0;
2052         return 1;
2053 }
2054
2055 STDCALL int
2056 mono_test_marshal_variant_in_short(VARIANT variant)
2057 {
2058         if (variant.vt == VT_I2 && variant.iVal == 314)
2059                 return 0;
2060         return 1;
2061 }
2062
2063 STDCALL int
2064 mono_test_marshal_variant_in_ushort(VARIANT variant)
2065 {
2066         if (variant.vt == VT_UI2 && variant.uiVal == 314)
2067                 return 0;
2068         return 1;
2069 }
2070
2071 STDCALL int
2072 mono_test_marshal_variant_in_int(VARIANT variant)
2073 {
2074         if (variant.vt == VT_I4 && variant.lVal == 314)
2075                 return 0;
2076         return 1;
2077 }
2078
2079 STDCALL int
2080 mono_test_marshal_variant_in_uint(VARIANT variant)
2081 {
2082         if (variant.vt == VT_UI4 && variant.ulVal == 314)
2083                 return 0;
2084         return 1;
2085 }
2086
2087 STDCALL int
2088 mono_test_marshal_variant_in_long(VARIANT variant)
2089 {
2090         if (variant.vt == VT_I8 && variant.llVal == 314)
2091                 return 0;
2092         return 1;
2093 }
2094
2095 STDCALL int
2096 mono_test_marshal_variant_in_ulong(VARIANT variant)
2097 {
2098         if (variant.vt == VT_UI8 && variant.ullVal == 314)
2099                 return 0;
2100         return 1;
2101 }
2102
2103 STDCALL int
2104 mono_test_marshal_variant_in_float(VARIANT variant)
2105 {
2106         if (variant.vt == VT_R4 && (variant.fltVal - 3.14)/3.14 < .001)
2107                 return 0;
2108         return 1;
2109 }
2110
2111 STDCALL int
2112 mono_test_marshal_variant_in_double(VARIANT variant)
2113 {
2114         if (variant.vt == VT_R8 && (variant.dblVal - 3.14)/3.14 < .001)
2115                 return 0;
2116         return 1;
2117 }
2118
2119 STDCALL int
2120 mono_test_marshal_variant_in_bstr(VARIANT variant)
2121 {
2122         if (variant.vt == VT_BSTR && !wcscmp(variant.bstrVal, L"PI"))
2123                 return 0;
2124         return 1;
2125 }
2126
2127 STDCALL int
2128 mono_test_marshal_variant_in_bool_true (VARIANT variant)
2129 {
2130         if (variant.vt == VT_BOOL && variant.ullVal == VARIANT_TRUE)
2131                 return 0;
2132         return 1;
2133 }
2134
2135 STDCALL int
2136 mono_test_marshal_variant_in_bool_false (VARIANT variant)
2137 {
2138         if (variant.vt == VT_BOOL && variant.ullVal == VARIANT_FALSE)
2139                 return 0;
2140         return 1;
2141 }
2142
2143 STDCALL int
2144 mono_test_marshal_variant_out_sbyte(VARIANT* variant)
2145 {
2146         variant->vt = VT_I1;
2147         variant->cVal = 100;
2148
2149         return 0;
2150 }
2151
2152 STDCALL int
2153 mono_test_marshal_variant_out_byte(VARIANT* variant)
2154 {       
2155         variant->vt = VT_UI1;
2156         variant->bVal = 100;
2157
2158         return 0;
2159 }
2160
2161 STDCALL int
2162 mono_test_marshal_variant_out_short(VARIANT* variant)
2163 {
2164         variant->vt = VT_I2;
2165         variant->iVal = 314;
2166
2167         return 0;
2168 }
2169
2170 STDCALL int
2171 mono_test_marshal_variant_out_ushort(VARIANT* variant)
2172 {
2173         variant->vt = VT_UI2;
2174         variant->uiVal = 314;
2175
2176         return 0;
2177 }
2178
2179 STDCALL int
2180 mono_test_marshal_variant_out_int(VARIANT* variant)
2181 {
2182         variant->vt = VT_I4;
2183         variant->lVal = 314;
2184
2185         return 0;
2186 }
2187
2188 STDCALL int
2189 mono_test_marshal_variant_out_uint(VARIANT* variant)
2190 {
2191         variant->vt = VT_UI4;
2192         variant->ulVal = 314;
2193
2194         return 0;
2195 }
2196
2197 STDCALL int
2198 mono_test_marshal_variant_out_long(VARIANT* variant)
2199 {
2200         variant->vt = VT_I8;
2201         variant->llVal = 314;
2202
2203         return 0;
2204 }
2205
2206 STDCALL int
2207 mono_test_marshal_variant_out_ulong(VARIANT* variant)
2208 {
2209         variant->vt = VT_UI8;
2210         variant->ullVal = 314;
2211
2212         return 0;
2213 }
2214
2215 STDCALL int
2216 mono_test_marshal_variant_out_float(VARIANT* variant)
2217 {
2218         variant->vt = VT_R4;
2219         variant->fltVal = 3.14;
2220
2221         return 0;
2222 }
2223
2224 STDCALL int
2225 mono_test_marshal_variant_out_double(VARIANT* variant)
2226 {
2227         variant->vt = VT_R8;
2228         variant->dblVal = 3.14;
2229
2230         return 0;
2231 }
2232
2233 STDCALL int
2234 mono_test_marshal_variant_out_bstr(VARIANT* variant)
2235 {
2236         variant->vt = VT_BSTR;
2237         variant->bstrVal = SysAllocString(L"PI");
2238
2239         return 0;
2240 }
2241
2242 STDCALL int
2243 mono_test_marshal_variant_out_bool_true (VARIANT* variant)
2244 {
2245         variant->vt = VT_BOOL;
2246         variant->bstrVal = VARIANT_TRUE;
2247
2248         return 0;
2249 }
2250
2251 STDCALL int
2252 mono_test_marshal_variant_out_bool_false (VARIANT* variant)
2253 {
2254         variant->vt = VT_BOOL;
2255         variant->bstrVal = VARIANT_FALSE;
2256
2257         return 0;
2258 }
2259
2260 #ifdef _MSC_VER
2261 #define COM_STDCALL __stdcall
2262 #else
2263 #define COM_STDCALL __attribute__((stdcall))
2264 #endif
2265
2266 typedef struct MonoComObject MonoComObject;
2267
2268 typedef struct
2269 {
2270         int (COM_STDCALL *QueryInterface)(MonoComObject* pUnk, gpointer riid, gpointer* ppv);
2271         int (COM_STDCALL *AddRef)(MonoComObject* pUnk);
2272         int (COM_STDCALL *Release)(MonoComObject* pUnk);
2273         int (COM_STDCALL *Add)(MonoComObject* pUnk, int a, int b, int* c);
2274         int (COM_STDCALL *Subtract)(MonoComObject* pUnk, int a, int b, int* c);
2275         int (COM_STDCALL *Same)(MonoComObject* pUnk, MonoComObject* *pOut);
2276         int (COM_STDCALL *Different)(MonoComObject* pUnk, MonoComObject* *pOut);
2277 } MonoIUnknown;
2278
2279 struct MonoComObject
2280 {
2281         MonoIUnknown* vtbl;
2282         int m_ref;
2283 };
2284
2285 DEFINE_GUID(IID_IMath, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);
2286 DEFINE_GUID(IID_IMonoUnknown, 0, 0, 0, 0xC0, 0, 0, 0, 0, 0, 0, 0x46);
2287 DEFINE_GUID(IID_IMonoDispatch, 0x00020400, 0, 0, 0xC0, 0, 0, 0, 0, 0, 0, 0x46);
2288
2289 int COM_STDCALL MonoQueryInterface(MonoComObject* pUnk, gpointer riid, gpointer* ppv)
2290 {
2291         *ppv = NULL;
2292         if (!memcmp(riid, &IID_IMonoUnknown, sizeof(GUID))) {
2293                 *ppv = pUnk;
2294                 return S_OK;
2295         }
2296         else if (!memcmp(riid, &IID_IMath, sizeof(GUID))) {
2297                 *ppv = pUnk;
2298                 return S_OK;
2299         }
2300         else if (!memcmp(riid, &IID_IMonoDispatch, sizeof(GUID))) {
2301                 *ppv = pUnk;
2302                 return S_OK;
2303         }
2304         return E_NOINTERFACE;
2305 }
2306
2307 int COM_STDCALL MonoAddRef(MonoComObject* pUnk)
2308 {
2309         return ++(pUnk->m_ref);
2310 }
2311
2312 int COM_STDCALL MonoRelease(MonoComObject* pUnk)
2313 {
2314         return --(pUnk->m_ref);
2315 }
2316
2317 int COM_STDCALL Add(MonoComObject* pUnk, int a, int b, int* c)
2318 {
2319         *c = a + b;
2320         return 0;
2321 }
2322
2323 int COM_STDCALL Subtract(MonoComObject* pUnk, int a, int b, int* c)
2324 {
2325         *c = a - b;
2326         return 0;
2327 }
2328
2329 static void create_com_object (MonoComObject** pOut);
2330 static MonoComObject* same_com_object = NULL;
2331
2332 int COM_STDCALL Same(MonoComObject* pUnk, MonoComObject** pOut)
2333 {
2334         if (!same_com_object)
2335                 create_com_object (&same_com_object);
2336         *pOut = same_com_object;
2337         return 0;
2338 }
2339
2340 int COM_STDCALL Different(MonoComObject* pUnk, MonoComObject** pOut)
2341 {
2342         create_com_object (pOut);
2343         return 0;
2344 }
2345
2346 static void create_com_object (MonoComObject** pOut)
2347 {
2348         *pOut = g_new0 (MonoComObject, 1);
2349         (*pOut)->vtbl = g_new0 (MonoIUnknown, 1);
2350
2351         (*pOut)->m_ref = 1;
2352         (*pOut)->vtbl->QueryInterface = MonoQueryInterface;
2353         (*pOut)->vtbl->AddRef = MonoAddRef;
2354         (*pOut)->vtbl->Release = MonoRelease;
2355         (*pOut)->vtbl->Add = Add;
2356         (*pOut)->vtbl->Subtract = Subtract;
2357         (*pOut)->vtbl->Same = Same;
2358         (*pOut)->vtbl->Different = Different;
2359 }
2360
2361 STDCALL int
2362 mono_test_marshal_com_object_create(MonoComObject* *pUnk)
2363 {
2364         create_com_object (pUnk);
2365
2366         return 0;
2367 }
2368
2369 STDCALL int
2370 mono_test_marshal_com_object_destroy(MonoComObject *pUnk)
2371 {
2372         int ref = --(pUnk->m_ref);
2373         g_free(pUnk->vtbl);
2374         g_free(pUnk);
2375
2376         return ref;
2377 }
2378
2379 STDCALL int
2380 mono_test_marshal_com_object_ref_count(MonoComObject *pUnk)
2381 {
2382         return pUnk->m_ref;
2383 }
2384 #endif //NOT_YET