2007-10-19 Marek Habersack <mhabersack@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         marshal_free (ss->d);
420
421         ss->a = !ss->a;
422         ss->b = !ss->b;
423         ss->c = !ss->c;
424         ss->d = g_strdup ("DEF");
425
426         return res ? 0 : 1;
427 }
428
429 typedef struct {
430         int a;
431         int b;
432         int c;
433         char *d;
434         unsigned char e;
435         double f;
436         unsigned char g;
437         guint64 h;
438 } simplestruct2;
439
440 STDCALL int
441 mono_test_marshal_struct2 (simplestruct2 ss)
442 {
443         if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
444             !strcmp (ss.d, "TEST") && 
445             ss.e == 99 && ss.f == 1.5 && ss.g == 42 && ss.h == (guint64)123)
446                 return 0;
447
448         return 1;
449 }
450
451 /* on HP some of the struct should be on the stack and not in registers */
452 STDCALL int
453 mono_test_marshal_struct2_2 (int i, int j, int k, simplestruct2 ss)
454 {
455         if (i != 10 || j != 11 || k != 12)
456                 return 1;
457         if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
458             !strcmp (ss.d, "TEST") && 
459             ss.e == 99 && ss.f == 1.5 && ss.g == 42 && ss.h == (guint64)123)
460                 return 0;
461
462         return 1;
463 }
464
465 STDCALL int 
466 mono_test_marshal_lpstruct (simplestruct *ss)
467 {
468         if (ss->a == 0 && ss->b == 1 && ss->c == 0 &&
469             !strcmp (ss->d, "TEST"))
470                 return 0;
471
472         return 1;
473 }
474
475 STDCALL int 
476 mono_test_marshal_lpstruct_blittable (point *p)
477 {
478         if (p->x == 1.0 && p->y == 2.0)
479                 return 0;
480         else
481                 return 1;
482 }
483
484 STDCALL int
485 mono_test_marshal_struct_array (simplestruct2 *ss)
486 {
487         if (! (ss[0].a == 0 && ss[0].b == 1 && ss[0].c == 0 &&
488                    !strcmp (ss[0].d, "TEST") && 
489                    ss[0].e == 99 && ss[0].f == 1.5 && ss[0].g == 42 && ss[0].h == (guint64)123))
490                 return 1;
491
492         if (! (ss[1].a == 0 && ss[1].b == 0 && ss[1].c == 0 &&
493                    !strcmp (ss[1].d, "TEST2") && 
494                    ss[1].e == 100 && ss[1].f == 2.5 && ss[1].g == 43 && ss[1].h == (guint64)124))
495                 return 1;
496
497         return 0;
498 }
499
500 typedef struct long_align_struct {
501         gint32 a;
502         gint64 b;
503         gint64 c;
504 } long_align_struct;
505
506 STDCALL int
507 mono_test_marshal_long_align_struct_array (long_align_struct *ss)
508 {
509         return ss[0].a + ss[0].b + ss[0].c + ss[1].a + ss[1].b + ss[1].c;
510 }
511
512 STDCALL simplestruct2 *
513 mono_test_marshal_class (int i, int j, int k, simplestruct2 *ss, int l)
514 {
515         simplestruct2 *res;
516
517         if (!ss)
518                 return NULL;
519
520         if (i != 10 || j != 11 || k != 12 || l != 14)
521                 return NULL;
522         if (! (ss->a == 0 && ss->b == 1 && ss->c == 0 &&
523                    !strcmp (ss->d, "TEST") && 
524                    ss->e == 99 && ss->f == 1.5 && ss->g == 42 && ss->h == (guint64)123))
525                 return NULL;
526
527         res = g_new0 (simplestruct2, 1);
528         memcpy (res, ss, sizeof (simplestruct2));
529         res->d = g_strdup ("TEST");
530         return res;
531 }
532
533 STDCALL int
534 mono_test_marshal_byref_class (simplestruct2 **ssp)
535 {
536         simplestruct2 *ss = *ssp;
537         simplestruct2 *res;
538         
539         if (! (ss->a == 0 && ss->b == 1 && ss->c == 0 &&
540                    !strcmp (ss->d, "TEST") && 
541                    ss->e == 99 && ss->f == 1.5 && ss->g == 42 && ss->h == (guint64)123))
542                 return 1;
543
544         res = g_new0 (simplestruct2, 1);
545         memcpy (res, ss, sizeof (simplestruct2));
546         res->d = g_strdup ("TEST-RES");
547
548         *ssp = res;
549         return 0;
550 }
551
552 static void *
553 get_sp (void)
554 {
555         int i;
556         void *p;
557
558         /* Yes, this is correct, we are only trying to determine the value of the stack here */
559         p = &i;
560         return p;
561 }
562
563 STDCALL int
564 reliable_delegate (int a)
565 {
566         return a;
567 }
568
569 /*
570  * Checks whether get_sp() works as expected. It doesn't work with gcc-2.95.3 on linux.
571  */
572 static gboolean
573 is_get_sp_reliable (void)
574 {
575         void *sp1, *sp2;
576
577         reliable_delegate(1);
578         sp1 = get_sp();
579         reliable_delegate(1);
580         sp2 = get_sp();
581         return sp1 == sp2;
582
583
584 STDCALL int
585 mono_test_marshal_delegate (SimpleDelegate delegate)
586 {
587         void *sp1, *sp2;
588
589         /* Check that the delegate wrapper is stdcall */
590         delegate (2);
591         sp1 = get_sp ();
592         delegate (2);
593         sp2 = get_sp ();
594         if (is_get_sp_reliable())
595                 g_assert (sp1 == sp2);
596
597         return delegate (2);
598 }
599
600 STDCALL SimpleDelegate
601 mono_test_marshal_return_delegate (SimpleDelegate delegate)
602 {
603         return delegate;
604 }
605
606 static STDCALL int
607 return_plus_one (int i)
608 {
609         return i + 1;
610 }
611
612 STDCALL SimpleDelegate
613 mono_test_marshal_return_delegate_2 ()
614 {
615         return return_plus_one;
616 }
617
618 typedef simplestruct (STDCALL *SimpleDelegate2) (simplestruct ss);
619
620 static gboolean
621 is_utf16_equals (gunichar2 *s1, const char *s2)
622 {
623         char *s;
624         int res;
625
626         s = g_utf16_to_utf8 (s1, -1, NULL, NULL, NULL);
627         res = strcmp (s, s2);
628         g_free (s);
629
630         return res == 0;
631 }
632
633 STDCALL int
634 mono_test_marshal_delegate2 (SimpleDelegate2 delegate)
635 {
636         simplestruct ss, res;
637
638         ss.a = 0;
639         ss.b = 1;
640         ss.c = 0;
641         ss.d = "TEST";
642         ss.d2 = g_utf8_to_utf16 ("TEST2", -1, NULL, NULL, NULL); 
643
644         res = delegate (ss);
645         if (! (res.a && !res.b && res.c && !strcmp (res.d, "TEST-RES") && is_utf16_equals (res.d2, "TEST2-RES")))
646                 return 1;
647
648         return 0;
649 }
650
651 typedef simplestruct* (STDCALL *SimpleDelegate4) (simplestruct *ss);
652
653 STDCALL int
654 mono_test_marshal_delegate4 (SimpleDelegate4 delegate)
655 {
656         simplestruct ss;
657         simplestruct *res;
658
659         ss.a = 0;
660         ss.b = 1;
661         ss.c = 0;
662         ss.d = "TEST";
663
664         /* Check argument */
665         res = delegate (&ss);
666         if (!res)
667                 return 1;
668
669         /* Check return value */
670         if (! (!res->a && res->b && !res->c && !strcmp (res->d, "TEST")))
671                 return 2;
672
673         /* Check NULL argument and NULL result */
674         res = delegate (NULL);
675         if (res)
676                 return 3;
677
678         return 0;
679 }
680
681 typedef int (STDCALL *SimpleDelegate5) (simplestruct **ss);
682
683 STDCALL int
684 mono_test_marshal_delegate5 (SimpleDelegate5 delegate)
685 {
686         simplestruct ss;
687         int res;
688         simplestruct *ptr;
689
690         ss.a = 0;
691         ss.b = 1;
692         ss.c = 0;
693         ss.d = "TEST";
694
695         ptr = &ss;
696
697         res = delegate (&ptr);
698         if (res != 0)
699                 return 1;
700
701         if (!(ptr->a && !ptr->b && ptr->c && !strcmp (ptr->d, "RES")))
702                 return 2;
703
704         return 0;
705 }
706
707 STDCALL int
708 mono_test_marshal_delegate6 (SimpleDelegate5 delegate)
709 {
710         int res;
711
712         res = delegate (NULL);
713
714         return 0;
715 }
716
717 typedef int (STDCALL *SimpleDelegate7) (simplestruct **ss);
718
719 STDCALL int
720 mono_test_marshal_delegate7 (SimpleDelegate7 delegate)
721 {
722         int res;
723         simplestruct *ptr;
724
725         /* Check that the input pointer is ignored */
726         ptr = (gpointer)0x12345678;
727
728         res = delegate (&ptr);
729         if (res != 0)
730                 return 1;
731
732         if (!(ptr->a && !ptr->b && ptr->c && !strcmp (ptr->d, "RES")))
733                 return 2;
734
735         return 0;
736 }
737
738 typedef int (STDCALL *InOutByvalClassDelegate) (simplestruct *ss);
739
740 STDCALL int
741 mono_test_marshal_inout_byval_class_delegate (InOutByvalClassDelegate delegate)
742 {
743         int res;
744         simplestruct ss;
745
746         ss.a = FALSE;
747         ss.b = TRUE;
748         ss.c = FALSE;
749         ss.d = g_strdup_printf ("%s", "FOO");
750
751         res = delegate (&ss);
752         if (res != 0)
753                 return 1;
754
755         if (!(ss.a && !ss.b && ss.c && !strcmp (ss.d, "RES")))
756                 return 2;
757
758         return 0;
759 }
760
761 typedef int (STDCALL *SimpleDelegate8) (gunichar2 *s);
762
763 STDCALL int
764 mono_test_marshal_delegate8 (SimpleDelegate8 delegate, gunichar2 *s)
765 {
766         return delegate (s);
767 }
768
769 typedef int (STDCALL *return_int_fnt) (int i);
770 typedef int (STDCALL *SimpleDelegate9) (return_int_fnt d);
771
772 STDCALL int
773 mono_test_marshal_delegate9 (SimpleDelegate9 delegate, gpointer ftn)
774 {
775         return delegate (ftn);
776 }
777
778 STDCALL static int
779 return_self (int i)
780 {
781         return i;
782 }
783
784 STDCALL int
785 mono_test_marshal_delegate10 (SimpleDelegate9 delegate)
786 {
787         return delegate (return_self);
788 }
789
790 typedef int (STDCALL *PrimitiveByrefDelegate) (int *i);
791
792 STDCALL int
793 mono_test_marshal_primitive_byref_delegate (PrimitiveByrefDelegate delegate)
794 {
795         int i = 1;
796
797         int res = delegate (&i);
798         if (res != 0)
799                 return res;
800
801         if (i != 2)
802                 return 2;
803
804         return 0;
805 }
806
807 typedef int (STDCALL *return_int_delegate) (int i);
808
809 typedef return_int_delegate (STDCALL *ReturnDelegateDelegate) (void);
810
811 STDCALL int
812 mono_test_marshal_return_delegate_delegate (ReturnDelegateDelegate d)
813 {
814         return (d ()) (55);
815 }
816
817 STDCALL int 
818 mono_test_marshal_stringbuilder (char *s, int n)
819 {
820         const char m[] = "This is my message.  Isn't it nice?";
821
822         if (strcmp (s, "ABCD") != 0)
823                 return 1;
824         strncpy(s, m, n);
825         s [n] = '\0';
826         return 0;
827 }
828
829 STDCALL int 
830 mono_test_marshal_stringbuilder_default (char *s, int n)
831 {
832         const char m[] = "This is my message.  Isn't it nice?";
833
834         strncpy(s, m, n);
835         s [n] = '\0';
836         return 0;
837 }
838
839 STDCALL int 
840 mono_test_marshal_stringbuilder_unicode (gunichar2 *s, int n)
841 {
842         const char m[] = "This is my message.  Isn't it nice?";
843         gunichar2* s2;
844         glong len;
845
846         s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
847         
848         len = (len * 2) + 2;
849         if (len > (n * 2))
850                 len = n * 2;
851         memcpy (s, s2, len);
852
853         g_free (s2);
854
855         return 0;
856 }
857
858 typedef struct {
859 #ifndef __GNUC__
860     char a;
861 #endif
862 } EmptyStruct;
863
864 STDCALL int
865 mono_test_marshal_empty_string_array (char **array)
866 {
867         return (array == NULL) ? 0 : 1;
868 }
869
870 STDCALL int
871 mono_test_marshal_string_array (char **array)
872 {
873         if (strcmp (array [0], "ABC"))
874                 return 1;
875         if (strcmp (array [1], "DEF"))
876                 return 2;
877
878         if (array [2] != NULL)
879                 return 3;
880
881         return 0;
882 }
883
884 STDCALL int
885 mono_test_marshal_byref_string_array (char ***array)
886 {
887         if (*array == NULL)
888                 return 0;
889
890         if (strcmp ((*array) [0], "Alpha"))
891                 return 2;
892         if (strcmp ((*array) [1], "Beta"))
893                 return 2;
894         if (strcmp ((*array) [2], "Gamma"))
895                 return 2;
896
897         return 1;
898 }
899
900 STDCALL int
901 mono_test_marshal_stringbuilder_array (char **array)
902 {
903         if (strcmp (array [0], "ABC"))
904                 return 1;
905         if (strcmp (array [1], "DEF"))
906                 return 2;
907
908         strcpy (array [0], "DEF");
909         strcpy (array [1], "ABC");
910
911         return 0;
912 }
913
914 STDCALL int
915 mono_test_marshal_unicode_string_array (gunichar2 **array, char **array2)
916 {
917         GError *error = NULL;
918         char *s;
919         
920         s = g_utf16_to_utf8 (array [0], -1, NULL, NULL, &error);
921         if (strcmp (s, "ABC")) {
922                 g_free (s);
923                 return 1;
924         }
925         else
926                 g_free (s);
927
928         s = g_utf16_to_utf8 (array [1], -1, NULL, NULL, &error);
929         if (strcmp (s, "DEF")) {
930                 g_free (s);
931                 return 2;
932         }
933         else
934                 g_free (s);
935
936         if (strcmp (array2 [0], "ABC"))
937                 return 3;
938
939         if (strcmp (array2 [1], "DEF")) 
940                 return 4;
941
942         return 0;
943 }
944
945 /* this does not work on Redhat gcc 2.96 */
946 STDCALL int 
947 mono_test_empty_struct (int a, EmptyStruct es, int b)
948 {
949         // printf ("mono_test_empty_struct %d %d\n", a, b);
950
951         // Intel icc on ia64 passes 'es' in 2 registers
952 #if defined(__ia64) && defined(__INTEL_COMPILER)
953         return 0;
954 #else
955         if (a == 1 && b == 2)
956                 return 0;
957         return 1;
958 #endif
959 }
960
961 typedef struct {
962        char a[100];
963 } ByValStrStruct;
964
965 STDCALL ByValStrStruct *
966 mono_test_byvalstr_gen (void)
967 {
968         ByValStrStruct *ret;
969        
970         ret = malloc(sizeof(ByValStrStruct));
971         memset(ret, 'a', sizeof(ByValStrStruct)-1);
972         ret->a[sizeof(ByValStrStruct)-1] = 0;
973
974         return ret;
975 }
976
977 STDCALL int
978 mono_test_byvalstr_check (ByValStrStruct* data, char* correctString)
979 {
980         int ret;
981
982         ret = strcmp(data->a, correctString);
983         // printf ("T1: %s\n", data->a);
984         // printf ("T2: %s\n", correctString);
985
986         marshal_free (data);
987         return (ret != 0);
988 }
989
990 typedef struct {
991         guint16 a[4];
992         int  flag;
993 } ByValStrStruct_Unicode;
994
995 STDCALL int
996 mono_test_byvalstr_check_unicode (ByValStrStruct_Unicode *ref, int test)
997 {
998         if (ref->flag != 0x1234abcd){
999                 printf ("overwritten data");
1000                 return 1;
1001         }
1002             
1003         if (test == 1 || test == 3){
1004                 if (ref->a [0] != '1' ||
1005                     ref->a [1] != '2'   ||
1006                     ref->a [2] != '3')
1007                         return 1;
1008                 return 0;
1009         }
1010         if (test == 2){
1011                 if (ref->a [0] != '1' ||
1012                     ref->a [1] != '2')
1013                         return 1;
1014                 return 0;
1015         }
1016         return 10;
1017 }
1018
1019 STDCALL int
1020 NameManglingAnsi (char *data)
1021 {
1022         return data [0] + data [1] + data [2];
1023 }
1024
1025 STDCALL int
1026 NameManglingAnsiA (char *data)
1027 {
1028         g_assert_not_reached ();
1029 }
1030
1031 STDCALL int
1032 NameManglingAnsiW (char *data)
1033 {
1034         g_assert_not_reached ();
1035 }
1036
1037 STDCALL int
1038 NameManglingAnsi2A (char *data)
1039 {
1040         return data [0] + data [1] + data [2];
1041 }
1042
1043 STDCALL int
1044 NameManglingAnsi2W (char *data)
1045 {
1046         g_assert_not_reached ();
1047 }
1048
1049 STDCALL int
1050 NameManglingUnicode (char *data)
1051 {
1052         g_assert_not_reached ();
1053 }
1054
1055 STDCALL int
1056 NameManglingUnicodeW (gunichar2 *data)
1057 {
1058         return data [0] + data [1] + data [2];
1059 }
1060
1061 STDCALL int
1062 NameManglingUnicode2 (gunichar2 *data)
1063 {
1064         return data [0] + data [1] + data [2];
1065 }
1066
1067 STDCALL int
1068 NameManglingAutoW (char *data)
1069 {
1070 #ifdef WIN32
1071         return (data [0] + data [1] + data [2]) == 131 ? 0 : 1;
1072 #else
1073         g_assert_not_reached ();
1074 #endif
1075 }
1076
1077 STDCALL int
1078 NameManglingAuto (char *data)
1079 {
1080 #ifndef WIN32
1081         return (data [0] + data [1] + data [2]) == 198 ? 0 : 1;
1082 #else
1083         g_assert_not_reached ();
1084 #endif
1085 }
1086
1087 typedef int (STDCALL *intcharFunc)(const char*);
1088
1089 STDCALL void 
1090 callFunction (intcharFunc f)
1091 {
1092         f ("ABC");
1093 }
1094
1095 typedef struct {
1096         const char* str;
1097         int i;
1098 } SimpleObj;
1099
1100 STDCALL int
1101 class_marshal_test0 (SimpleObj *obj1)
1102 {
1103         // printf ("class_marshal_test0 %s %d\n", obj1->str, obj1->i);
1104
1105         if (strcmp(obj1->str, "T1"))
1106                 return -1;
1107         if (obj1->i != 4)
1108                 return -2;
1109
1110         return 0;
1111 }
1112
1113 STDCALL int
1114 class_marshal_test4 (SimpleObj *obj1)
1115 {
1116         if (obj1)
1117                 return -1;
1118
1119         return 0;
1120 }
1121
1122 STDCALL void
1123 class_marshal_test1 (SimpleObj **obj1)
1124 {
1125         SimpleObj *res = malloc (sizeof (SimpleObj));
1126
1127         res->str = g_strdup ("ABC");
1128         res->i = 5;
1129
1130         *obj1 = res;
1131 }
1132
1133 STDCALL int
1134 class_marshal_test2 (SimpleObj **obj1)
1135 {
1136         // printf ("class_marshal_test2 %s %d\n", (*obj1)->str, (*obj1)->i);
1137
1138         if (strcmp((*obj1)->str, "ABC"))
1139                 return -1;
1140         if ((*obj1)->i != 5)
1141                 return -2;
1142
1143         return 0;
1144 }
1145
1146 STDCALL int
1147 string_marshal_test0 (char *str)
1148 {
1149         if (strcmp (str, "TEST0"))
1150                 return -1;
1151
1152         return 0;
1153 }
1154
1155 STDCALL void
1156 string_marshal_test1 (const char **str)
1157 {
1158         *str = "TEST1";
1159 }
1160
1161 STDCALL int
1162 string_marshal_test2 (char **str)
1163 {
1164         // printf ("string_marshal_test2 %s\n", *str);
1165
1166         if (strcmp (*str, "TEST1"))
1167                 return -1;
1168
1169         return 0;
1170 }
1171
1172 STDCALL int
1173 string_marshal_test3 (char *str)
1174 {
1175         if (str)
1176                 return -1;
1177
1178         return 0;
1179 }
1180
1181 typedef struct {
1182         int a;
1183         int b;
1184 } BlittableClass;
1185
1186 STDCALL BlittableClass* 
1187 TestBlittableClass (BlittableClass *vl)
1188 {
1189         BlittableClass *res;
1190
1191         // printf ("TestBlittableClass %d %d\n", vl->a, vl->b);
1192
1193         if (vl) {
1194                 vl->a++;
1195                 vl->b++;
1196
1197                 res = g_new0 (BlittableClass, 1);
1198                 memcpy (res, vl, sizeof (BlittableClass));
1199         } else {
1200                 res = g_new0 (BlittableClass, 1);
1201                 res->a = 42;
1202                 res->b = 43;
1203         }
1204
1205         return res;
1206 }
1207
1208 typedef struct OSVERSIONINFO_STRUCT
1209
1210         int a; 
1211         int b; 
1212 } OSVERSIONINFO_STRUCT;
1213
1214 STDCALL int 
1215 MyGetVersionEx (OSVERSIONINFO_STRUCT *osvi)
1216 {
1217
1218         // printf ("GOT %d %d\n", osvi->a, osvi->b);
1219
1220         osvi->a += 1;
1221         osvi->b += 1;
1222
1223         return osvi->a + osvi->b;
1224 }
1225
1226 STDCALL int 
1227 BugGetVersionEx (int a, int b, int c, int d, int e, int f, int g, int h, OSVERSIONINFO_STRUCT *osvi)
1228 {
1229
1230         // printf ("GOT %d %d\n", osvi->a, osvi->b);
1231
1232         osvi->a += 1;
1233         osvi->b += 1;
1234
1235         return osvi->a + osvi->b;
1236 }
1237
1238 STDCALL int
1239 mono_test_marshal_point (point pt)
1240 {
1241         // printf("point %g %g\n", pt.x, pt.y);
1242         if (pt.x == 1.25 && pt.y == 3.5)
1243                 return 0;
1244
1245         return 1;
1246 }
1247
1248 typedef struct {
1249         int x;
1250         double y;
1251 } mixed_point;
1252
1253 STDCALL int
1254 mono_test_marshal_mixed_point (mixed_point pt)
1255 {
1256         // printf("mixed point %d %g\n", pt.x, pt.y);
1257         if (pt.x == 5 && pt.y == 6.75)
1258                 return 0;
1259
1260         return 1;
1261 }
1262
1263 STDCALL int
1264 mono_test_marshal_mixed_point_2 (mixed_point *pt)
1265 {
1266         if (pt->x != 5 || pt->y != 6.75)
1267                 return 1;
1268
1269         pt->x = 10;
1270         pt->y = 12.35;
1271
1272         return 0;
1273 }
1274
1275 STDCALL int 
1276 marshal_test_ref_bool(int i, char *b1, short *b2, int *b3)
1277 {
1278     int res = 1;
1279     if (*b1 != 0 && *b1 != 1)
1280         return 1;
1281     if (*b2 != 0 && *b2 != -1) /* variant_bool */
1282         return 1;
1283     if (*b3 != 0 && *b3 != 1)
1284         return 1;
1285     if (i == ((*b1 << 2) | (-*b2 << 1) | *b3))
1286         res = 0;
1287     *b1 = !*b1;
1288     *b2 = ~*b2;
1289     *b3 = !*b3;
1290     return res;
1291 }
1292
1293 struct BoolStruct
1294 {
1295     int i;
1296     char b1;
1297     short b2; /* variant_bool */
1298     int b3;
1299 };
1300
1301 STDCALL int 
1302 marshal_test_bool_struct(struct BoolStruct *s)
1303 {
1304     int res = 1;
1305     if (s->b1 != 0 && s->b1 != 1)
1306         return 1;
1307     if (s->b2 != 0 && s->b2 != -1)
1308         return 1;
1309     if (s->b3 != 0 && s->b3 != 1)
1310         return 1;
1311     if (s->i == ((s->b1 << 2) | (-s->b2 << 1) | s->b3))
1312         res = 0;
1313     s->b1 = !s->b1;
1314     s->b2 = ~s->b2;
1315     s->b3 = !s->b3;
1316     return res;
1317 }
1318
1319 STDCALL void
1320 mono_test_last_error (int err)
1321 {
1322 #ifdef WIN32
1323         SetLastError (err);
1324 #else
1325         errno = err;
1326 #endif
1327 }
1328
1329 STDCALL int
1330 mono_test_asany (void *ptr, int what)
1331 {
1332         switch (what) {
1333         case 1:
1334                 return (*(int*)ptr == 5) ? 0 : 1;
1335         case 2:
1336                 return strcmp (ptr, "ABC") == 0 ? 0 : 1;
1337         case 3: {
1338                 simplestruct2 ss = *(simplestruct2*)ptr;
1339
1340                 if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
1341             !strcmp (ss.d, "TEST") && 
1342             ss.e == 99 && ss.f == 1.5 && ss.g == 42 && ss.h == (guint64)123)
1343                         return 0;
1344                 else
1345                         return 1;
1346         }
1347         case 4: {
1348                 GError *error = NULL;
1349                 char *s;
1350
1351                 s = g_utf16_to_utf8 (ptr, -1, NULL, NULL, &error);
1352                 if (!strcmp (s, "ABC")) {
1353                         g_free (s);
1354                         return 0;
1355                 }
1356                 else {
1357                         g_free (s);
1358                         return 1;
1359                 }
1360         }
1361         default:
1362                 g_assert_not_reached ();
1363         }
1364
1365         return 1;
1366 }
1367
1368 typedef struct
1369 {
1370         int i;
1371         int j;
1372         int k;
1373         char *s;
1374 } AsAnyStruct;
1375
1376 STDCALL int
1377 mono_test_marshal_asany_in (void* ptr)
1378 {
1379         AsAnyStruct* asAny = ptr;
1380         int res = asAny->i + asAny->j + asAny->k;
1381
1382         return res;
1383 }
1384
1385 STDCALL int
1386 mono_test_marshal_asany_inout (void* ptr)
1387 {
1388         AsAnyStruct* asAny = ptr;
1389         int res = asAny->i + asAny->j + asAny->k;
1390
1391         marshal_free (asAny->s);
1392
1393         asAny->i = 10;
1394         asAny->j = 20;
1395         asAny->k = 30;
1396         asAny->s = 0;
1397
1398         return res;
1399 }
1400
1401 STDCALL int
1402 mono_test_marshal_asany_out (void* ptr)
1403 {
1404         AsAnyStruct* asAny = ptr;
1405         int res = asAny->i + asAny->j + asAny->k;
1406
1407         asAny->i = 10;
1408         asAny->j = 20;
1409         asAny->k = 30;
1410         asAny->s = 0;
1411
1412         return res;
1413 }
1414
1415 /*
1416  * AMD64 marshalling tests.
1417  */
1418
1419 typedef struct amd64_struct1 {
1420         int i;
1421         int j;
1422         int k;
1423         int l;
1424 } amd64_struct1;
1425
1426 STDCALL amd64_struct1
1427 mono_test_marshal_amd64_pass_return_struct1 (amd64_struct1 s)
1428 {
1429         s.i ++;
1430         s.j ++;
1431         s.k ++;
1432         s.l ++;
1433
1434         return s;
1435 }
1436
1437 typedef struct amd64_struct2 {
1438         int i;
1439         int j;
1440 } amd64_struct2;
1441
1442 STDCALL amd64_struct2
1443 mono_test_marshal_amd64_pass_return_struct2 (amd64_struct2 s)
1444 {
1445         s.i ++;
1446         s.j ++;
1447
1448         return s;
1449 }
1450
1451 typedef struct amd64_struct3 {
1452         int i;
1453 } amd64_struct3;
1454
1455 STDCALL amd64_struct3
1456 mono_test_marshal_amd64_pass_return_struct3 (amd64_struct3 s)
1457 {
1458         s.i ++;
1459
1460         return s;
1461 }
1462
1463 typedef struct amd64_struct4 {
1464         double d1, d2;
1465 } amd64_struct4;
1466
1467 STDCALL amd64_struct4
1468 mono_test_marshal_amd64_pass_return_struct4 (amd64_struct4 s)
1469 {
1470         s.d1 ++;
1471         s.d2 ++;
1472
1473         return s;
1474 }
1475
1476 /*
1477  * IA64 marshalling tests.
1478  */
1479 typedef struct test_struct5 {
1480         float d1, d2;
1481 } test_struct5;
1482
1483 STDCALL test_struct5
1484 mono_test_marshal_ia64_pass_return_struct5 (double d1, double d2, test_struct5 s, double d3, double d4)
1485 {
1486         s.d1 += d1 + d2;
1487         s.d2 += d3 + d4;
1488
1489         return s;
1490 }
1491
1492 typedef struct test_struct6 {
1493         double d1, d2;
1494 } test_struct6;
1495
1496 STDCALL test_struct6
1497 mono_test_marshal_ia64_pass_return_struct6 (double d1, double d2, test_struct6 s, double d3, double d4)
1498 {
1499         s.d1 += d1 + d2;
1500         s.d2 += d3 + d4;
1501
1502         return s;
1503 }
1504
1505 static guint32 custom_res [2];
1506
1507 STDCALL void*
1508 mono_test_marshal_pass_return_custom (int i, guint32 *ptr, int j)
1509 {
1510         /* ptr will be freed by CleanupNative, so make a copy */
1511         custom_res [0] = 0; /* not allocated by AllocHGlobal */
1512         custom_res [1] = ptr [1];
1513
1514         return &custom_res;
1515 }
1516
1517 STDCALL int
1518 mono_test_marshal_pass_out_custom (int i, guint32 **ptr, int j)
1519 {
1520         custom_res [0] = 0;
1521         custom_res [1] = i + j + 10;
1522
1523         *ptr = custom_res;
1524
1525         return 0;
1526 }
1527
1528 STDCALL int
1529 mono_test_marshal_pass_inout_custom (int i, guint32 *ptr, int j)
1530 {
1531         ptr [0] = 0;
1532         ptr [1] = i + ptr [1] + j;
1533
1534         return 0;
1535 }
1536
1537 STDCALL int
1538 mono_test_marshal_pass_out_byval_custom (int i, guint32 *ptr, int j)
1539 {
1540         return ptr == NULL ? 0 : 1;
1541 }
1542
1543 STDCALL int
1544 mono_test_marshal_pass_byref_custom (int i, guint32 **ptr, int j)
1545 {
1546         (*ptr)[1] += i + j;
1547
1548         return 0;
1549 }
1550
1551 STDCALL void*
1552 mono_test_marshal_pass_return_custom2 (int i, guint32 *ptr, int j)
1553 {
1554         g_assert_not_reached ();
1555
1556         return NULL;
1557 }
1558
1559 STDCALL void*
1560 mono_test_marshal_pass_return_custom_null (int i, guint32 *ptr, int j)
1561 {
1562         g_assert (ptr == NULL);
1563
1564         return NULL;
1565 }
1566
1567 typedef void *(STDCALL *PassReturnPtrDelegate) (void *ptr);
1568
1569 STDCALL int
1570 mono_test_marshal_pass_return_custom_in_delegate (PassReturnPtrDelegate del)
1571 {
1572         guint32 buf [2];
1573         guint32 res;
1574         guint32 *ptr;
1575
1576         buf [0] = 0;
1577         buf [1] = 10;
1578
1579         ptr = del (&buf);
1580
1581         res = ptr [1];
1582
1583 #ifdef WIN32
1584         /* FIXME: Freed with FreeHGlobal */
1585 #else
1586         g_free (ptr);
1587 #endif
1588
1589         return res;
1590 }
1591
1592 STDCALL int
1593 mono_test_marshal_pass_return_custom_null_in_delegate (PassReturnPtrDelegate del)
1594 {
1595         void *ptr = del (NULL);
1596
1597         return (ptr == NULL) ? 15 : 0;
1598 }
1599
1600 typedef void (STDCALL *CustomOutParamDelegate) (void **pptr);
1601
1602 STDCALL int
1603 mono_test_marshal_custom_out_param_delegate (CustomOutParamDelegate del)
1604 {
1605         void* pptr = del;
1606
1607         del (&pptr);
1608
1609         if(pptr != NULL)
1610                 return 1;
1611
1612         return 0;
1613 }
1614
1615 typedef int (STDCALL *ReturnEnumDelegate) (int e);
1616
1617 STDCALL int
1618 mono_test_marshal_return_enum_delegate (ReturnEnumDelegate func)
1619 {
1620         return func (1);
1621 }
1622
1623 typedef struct {
1624         int a, b, c;
1625         gint64 d;
1626 } BlittableStruct;
1627         
1628 typedef BlittableStruct (STDCALL *SimpleDelegate10) (BlittableStruct ss);
1629
1630 STDCALL int
1631 mono_test_marshal_blittable_struct_delegate (SimpleDelegate10 delegate)
1632 {
1633         BlittableStruct ss, res;
1634
1635         ss.a = 1;
1636         ss.b = 2;
1637         ss.c = 3;
1638         ss.d = 55;
1639
1640         res = delegate (ss);
1641         if (! ((res.a == -1) && (res.b == -2) && (res.c == -3) && (res.d == -55)))
1642                 return 1;
1643
1644         return 0;
1645 }
1646
1647 STDCALL int
1648 mono_test_stdcall_name_mangling (int a, int b, int c)
1649 {
1650         return a + b + c;
1651 }
1652
1653 /*
1654  * PASSING AND RETURNING SMALL STRUCTURES FROM DELEGATES TESTS
1655  */
1656
1657 typedef struct {
1658         int i;
1659 } SmallStruct1;
1660         
1661 typedef SmallStruct1 (STDCALL *SmallStructDelegate1) (SmallStruct1 ss);
1662
1663 STDCALL int
1664 mono_test_marshal_small_struct_delegate1 (SmallStructDelegate1 delegate)
1665 {
1666         SmallStruct1 ss, res;
1667
1668         ss.i = 1;
1669
1670         res = delegate (ss);
1671         if (! (res.i == -1))
1672                 return 1;
1673
1674         return 0;
1675 }
1676
1677 typedef struct {
1678         gint16 i, j;
1679 } SmallStruct2;
1680         
1681 typedef SmallStruct2 (STDCALL *SmallStructDelegate2) (SmallStruct2 ss);
1682
1683 STDCALL int
1684 mono_test_marshal_small_struct_delegate2 (SmallStructDelegate2 delegate)
1685 {
1686         SmallStruct2 ss, res;
1687
1688         ss.i = 2;
1689         ss.j = 3;
1690
1691         res = delegate (ss);
1692         if (! ((res.i == -2) && (res.j == -3)))
1693                 return 1;
1694
1695         return 0;
1696 }
1697
1698 typedef struct {
1699         gint16 i;
1700         gint8 j;
1701 } SmallStruct3;
1702         
1703 typedef SmallStruct3 (STDCALL *SmallStructDelegate3) (SmallStruct3 ss);
1704
1705 STDCALL int
1706 mono_test_marshal_small_struct_delegate3 (SmallStructDelegate3 delegate)
1707 {
1708         SmallStruct3 ss, res;
1709
1710         ss.i = 1;
1711         ss.j = 2;
1712
1713         res = delegate (ss);
1714         if (! ((res.i == -1) && (res.j == -2)))
1715                 return 1;
1716
1717         return 0;
1718 }
1719
1720 typedef struct {
1721         gint16 i;
1722 } SmallStruct4;
1723         
1724 typedef SmallStruct4 (STDCALL *SmallStructDelegate4) (SmallStruct4 ss);
1725
1726 STDCALL int
1727 mono_test_marshal_small_struct_delegate4 (SmallStructDelegate4 delegate)
1728 {
1729         SmallStruct4 ss, res;
1730
1731         ss.i = 1;
1732
1733         res = delegate (ss);
1734         if (! (res.i == -1))
1735                 return 1;
1736
1737         return 0;
1738 }
1739
1740 typedef struct {
1741         gint64 i;
1742 } SmallStruct5;
1743         
1744 typedef SmallStruct5 (STDCALL *SmallStructDelegate5) (SmallStruct5 ss);
1745
1746 STDCALL int
1747 mono_test_marshal_small_struct_delegate5 (SmallStructDelegate5 delegate)
1748 {
1749         SmallStruct5 ss, res;
1750
1751         ss.i = 5;
1752
1753         res = delegate (ss);
1754         if (! (res.i == -5))
1755                 return 1;
1756
1757         return 0;
1758 }
1759
1760 typedef struct {
1761         int i, j;
1762 } SmallStruct6;
1763         
1764 typedef SmallStruct6 (STDCALL *SmallStructDelegate6) (SmallStruct6 ss);
1765
1766 STDCALL int
1767 mono_test_marshal_small_struct_delegate6 (SmallStructDelegate6 delegate)
1768 {
1769         SmallStruct6 ss, res;
1770
1771         ss.i = 1;
1772         ss.j = 2;
1773
1774         res = delegate (ss);
1775         if (! ((res.i == -1) && (res.j == -2)))
1776                 return 1;
1777
1778         return 0;
1779 }
1780
1781 typedef struct {
1782         int i;
1783         gint16 j;
1784 } SmallStruct7;
1785         
1786 typedef SmallStruct7 (STDCALL *SmallStructDelegate7) (SmallStruct7 ss);
1787
1788 STDCALL int
1789 mono_test_marshal_small_struct_delegate7 (SmallStructDelegate7 delegate)
1790 {
1791         SmallStruct7 ss, res;
1792
1793         ss.i = 1;
1794         ss.j = 2;
1795
1796         res = delegate (ss);
1797         if (! ((res.i == -1) && (res.j == -2)))
1798                 return 1;
1799
1800         return 0;
1801 }
1802
1803 typedef struct {
1804         float i;
1805 } SmallStruct8;
1806         
1807 typedef SmallStruct8 (STDCALL *SmallStructDelegate8) (SmallStruct8 ss);
1808
1809 STDCALL int
1810 mono_test_marshal_small_struct_delegate8 (SmallStructDelegate8 delegate)
1811 {
1812         SmallStruct8 ss, res;
1813
1814         ss.i = 1.0;
1815
1816         res = delegate (ss);
1817         if (! ((res.i == -1.0)))
1818                 return 1;
1819
1820         return 0;
1821 }
1822
1823 typedef struct {
1824         double i;
1825 } SmallStruct9;
1826         
1827 typedef SmallStruct9 (STDCALL *SmallStructDelegate9) (SmallStruct9 ss);
1828
1829 STDCALL int
1830 mono_test_marshal_small_struct_delegate9 (SmallStructDelegate9 delegate)
1831 {
1832         SmallStruct9 ss, res;
1833
1834         ss.i = 1.0;
1835
1836         res = delegate (ss);
1837         if (! ((res.i == -1.0)))
1838                 return 1;
1839
1840         return 0;
1841 }
1842
1843 typedef struct {
1844         float i, j;
1845 } SmallStruct10;
1846         
1847 typedef SmallStruct10 (STDCALL *SmallStructDelegate10) (SmallStruct10 ss);
1848
1849 STDCALL int
1850 mono_test_marshal_small_struct_delegate10 (SmallStructDelegate10 delegate)
1851 {
1852         SmallStruct10 ss, res;
1853
1854         ss.i = 1.0;
1855         ss.j = 2.0;
1856
1857         res = delegate (ss);
1858         if (! ((res.i == -1.0) && (res.j == -2.0)))
1859                 return 1;
1860
1861         return 0;
1862 }
1863
1864 typedef struct {
1865         float i;
1866         int j;
1867 } SmallStruct11;
1868         
1869 typedef SmallStruct11 (STDCALL *SmallStructDelegate11) (SmallStruct11 ss);
1870
1871 STDCALL int
1872 mono_test_marshal_small_struct_delegate11 (SmallStructDelegate11 delegate)
1873 {
1874         SmallStruct11 ss, res;
1875
1876         ss.i = 1.0;
1877         ss.j = 2;
1878
1879         res = delegate (ss);
1880         if (! ((res.i == -1.0) && (res.j == -2)))
1881                 return 1;
1882
1883         return 0;
1884 }
1885
1886 typedef int (STDCALL *ArrayDelegate) (int i, char *j, void *arr);
1887
1888 STDCALL int
1889 mono_test_marshal_array_delegate (void *arr, int len, ArrayDelegate del)
1890 {
1891         return del (len, NULL, arr);
1892 }
1893
1894 STDCALL int
1895 mono_test_marshal_out_array_delegate (int *arr, int len, ArrayDelegate del)
1896 {
1897         del (len, NULL, arr);
1898
1899         if ((arr [0] != 1) || (arr [1] != 2))
1900                 return 1;
1901         else
1902                 return 0;
1903 }
1904
1905 typedef gunichar2* (STDCALL *UnicodeStringDelegate) (gunichar2 *message);
1906
1907 STDCALL int
1908 mono_test_marshal_return_unicode_string_delegate (UnicodeStringDelegate del)
1909 {
1910         const char m[] = "abcdef";
1911         gunichar2 *s2, *res;
1912         glong len;
1913
1914         s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
1915
1916         res = del (s2);
1917
1918         marshal_free (res);
1919
1920         return 0;
1921 }
1922
1923 STDCALL int
1924 mono_test_marshal_out_string_array_delegate (char **arr, int len, ArrayDelegate del)
1925 {
1926         del (len, NULL, arr);
1927
1928         if (!strcmp (arr [0], "ABC") && !strcmp (arr [1], "DEF"))
1929                 return 0;
1930         else
1931                 return 1;
1932 }
1933
1934 typedef int (*CdeclDelegate) (int i, int j);
1935
1936 STDCALL int
1937 mono_test_marshal_cdecl_delegate (CdeclDelegate del)
1938 {
1939         int i;
1940
1941         for (i = 0; i < 1000; ++i)
1942                 del (1, 2);
1943
1944         return 0;
1945 }
1946
1947 typedef char** (*ReturnStringArrayDelegate) (int i);
1948
1949 STDCALL int
1950 mono_test_marshal_return_string_array_delegate (ReturnStringArrayDelegate d)
1951 {
1952         char **arr = d (2);
1953         int res;
1954
1955         if (arr == NULL)
1956                 return 3;
1957
1958         if (strcmp (arr [0], "ABC") || strcmp (arr [1], "DEF"))
1959                 res = 1;
1960         else
1961                 res = 0;
1962
1963         marshal_free (arr);
1964
1965         return res;
1966 }
1967
1968 STDCALL int
1969 add_delegate (int i, int j)
1970 {
1971         return i + j;
1972 }
1973
1974 STDCALL gpointer
1975 mono_test_marshal_return_fnptr (void)
1976 {
1977         return &add_delegate;
1978 }
1979
1980 STDCALL int
1981 mono_xr (int code)
1982 {
1983         printf ("codigo %x\n", code);
1984         return code + 1234;
1985 }
1986
1987 typedef struct {
1988         int handle;
1989 } HandleRef;
1990
1991 STDCALL HandleRef
1992 mono_xr_as_handle (int code)
1993 {
1994         HandleRef ref;
1995
1996         return ref;
1997 }
1998  
1999 typedef struct {
2000         int   a;
2001         void *handle1;
2002         void *handle2;
2003         int   b;
2004 } HandleStructs;
2005
2006 STDCALL int
2007 mono_safe_handle_struct_ref (HandleStructs *x)
2008 {
2009         printf ("Dingus Ref! \n");
2010         printf ("Values: %d %d %d %d\n", x->a, x->b, x->handle1, x->handle2);
2011         if (x->a != 1234)
2012                 return 1;
2013         if (x->b != 8743)
2014                 return 2;
2015
2016         if (x->handle1 != (void*) 0x7080feed)
2017                 return 3;
2018
2019         if (x->handle2 != (void*) 0x1234abcd)
2020                 return 4;
2021
2022         return 0xf00d;
2023 }
2024
2025 STDCALL int
2026 mono_safe_handle_struct (HandleStructs x)
2027 {
2028         printf ("Dingus Standard! \n");
2029         printf ("Values: %d %d %d %d\n", x.a, x.b, x.handle1, x.handle2);
2030         if (x.a != 1234)
2031                 return 1;
2032         if (x.b != 8743)
2033                 return 2;
2034
2035         if (x.handle1 != (void*) 0x7080feed)
2036                 return 3;
2037
2038         if (x.handle2 != (void*) 0x1234abcd)
2039                 return 4;
2040         
2041         return 0xf00f;
2042 }
2043
2044 typedef struct {
2045         void *a;
2046 } TrivialHandle;
2047
2048 STDCALL int
2049 mono_safe_handle_struct_simple (TrivialHandle x)
2050 {
2051         printf ("The value is %d\n", x.a);
2052         return ((int)x.a) * 2;
2053 }
2054
2055 STDCALL int
2056 mono_safe_handle_return ()
2057 {
2058         return 0x1000f00d;
2059 }
2060
2061 STDCALL void
2062 mono_safe_handle_ref (void **handle)
2063 {
2064         if (*handle != 0){
2065                 *handle = (void *) 0xbad;
2066                 return;
2067         }
2068
2069         *handle = (void *) 0x800d;
2070 }
2071 /*
2072  * COM INTEROP TESTS
2073  */
2074
2075 #ifdef WIN32
2076
2077 STDCALL int
2078 mono_test_marshal_bstr_in(BSTR bstr)
2079 {
2080         if (!wcscmp(bstr, L"mono_test_marshal_bstr_in"))
2081                 return 0;
2082         return 1;
2083 }
2084
2085 STDCALL int
2086 mono_test_marshal_bstr_out(BSTR* bstr)
2087 {
2088         *bstr = SysAllocString(L"mono_test_marshal_bstr_out");
2089         return 0;
2090 }
2091
2092 STDCALL int
2093 mono_test_marshal_bstr_in_null(BSTR bstr)
2094 {
2095         if (!bstr)
2096                 return 0;
2097         return 1;
2098 }
2099
2100 STDCALL int
2101 mono_test_marshal_bstr_out_null(BSTR* bstr)
2102 {
2103         *bstr = NULL;
2104         return 0;
2105 }
2106
2107 STDCALL int
2108 mono_test_marshal_variant_in_sbyte(VARIANT variant)
2109 {
2110         if (variant.vt == VT_I1 && variant.cVal == 100)
2111                 return 0;
2112         return 1;
2113 }
2114
2115 STDCALL int
2116 mono_test_marshal_variant_in_byte(VARIANT variant)
2117 {
2118         if (variant.vt == VT_UI1 && variant.bVal == 100)
2119                 return 0;
2120         return 1;
2121 }
2122
2123 STDCALL int
2124 mono_test_marshal_variant_in_short(VARIANT variant)
2125 {
2126         if (variant.vt == VT_I2 && variant.iVal == 314)
2127                 return 0;
2128         return 1;
2129 }
2130
2131 STDCALL int
2132 mono_test_marshal_variant_in_ushort(VARIANT variant)
2133 {
2134         if (variant.vt == VT_UI2 && variant.uiVal == 314)
2135                 return 0;
2136         return 1;
2137 }
2138
2139 STDCALL int
2140 mono_test_marshal_variant_in_int(VARIANT variant)
2141 {
2142         if (variant.vt == VT_I4 && variant.lVal == 314)
2143                 return 0;
2144         return 1;
2145 }
2146
2147 STDCALL int
2148 mono_test_marshal_variant_in_uint(VARIANT variant)
2149 {
2150         if (variant.vt == VT_UI4 && variant.ulVal == 314)
2151                 return 0;
2152         return 1;
2153 }
2154
2155 STDCALL int
2156 mono_test_marshal_variant_in_long(VARIANT variant)
2157 {
2158         if (variant.vt == VT_I8 && variant.llVal == 314)
2159                 return 0;
2160         return 1;
2161 }
2162
2163 STDCALL int
2164 mono_test_marshal_variant_in_ulong(VARIANT variant)
2165 {
2166         if (variant.vt == VT_UI8 && variant.ullVal == 314)
2167                 return 0;
2168         return 1;
2169 }
2170
2171 STDCALL int
2172 mono_test_marshal_variant_in_float(VARIANT variant)
2173 {
2174         if (variant.vt == VT_R4 && (variant.fltVal - 3.14)/3.14 < .001)
2175                 return 0;
2176         return 1;
2177 }
2178
2179 STDCALL int
2180 mono_test_marshal_variant_in_double(VARIANT variant)
2181 {
2182         if (variant.vt == VT_R8 && (variant.dblVal - 3.14)/3.14 < .001)
2183                 return 0;
2184         return 1;
2185 }
2186
2187 STDCALL int
2188 mono_test_marshal_variant_in_bstr(VARIANT variant)
2189 {
2190         if (variant.vt == VT_BSTR && !wcscmp(variant.bstrVal, L"PI"))
2191                 return 0;
2192         return 1;
2193 }
2194
2195 STDCALL int
2196 mono_test_marshal_variant_in_bool_true (VARIANT variant)
2197 {
2198         if (variant.vt == VT_BOOL && variant.boolVal == VARIANT_TRUE)
2199                 return 0;
2200         return 1;
2201 }
2202
2203 STDCALL int
2204 mono_test_marshal_variant_in_bool_false (VARIANT variant)
2205 {
2206         if (variant.vt == VT_BOOL && variant.boolVal == VARIANT_FALSE)
2207                 return 0;
2208         return 1;
2209 }
2210
2211 STDCALL int
2212 mono_test_marshal_variant_out_sbyte(VARIANT* variant)
2213 {
2214         variant->vt = VT_I1;
2215         variant->cVal = 100;
2216
2217         return 0;
2218 }
2219
2220 STDCALL int
2221 mono_test_marshal_variant_out_byte(VARIANT* variant)
2222 {       
2223         variant->vt = VT_UI1;
2224         variant->bVal = 100;
2225
2226         return 0;
2227 }
2228
2229 STDCALL int
2230 mono_test_marshal_variant_out_short(VARIANT* variant)
2231 {
2232         variant->vt = VT_I2;
2233         variant->iVal = 314;
2234
2235         return 0;
2236 }
2237
2238 STDCALL int
2239 mono_test_marshal_variant_out_ushort(VARIANT* variant)
2240 {
2241         variant->vt = VT_UI2;
2242         variant->uiVal = 314;
2243
2244         return 0;
2245 }
2246
2247 STDCALL int
2248 mono_test_marshal_variant_out_int(VARIANT* variant)
2249 {
2250         variant->vt = VT_I4;
2251         variant->lVal = 314;
2252
2253         return 0;
2254 }
2255
2256 STDCALL int
2257 mono_test_marshal_variant_out_uint(VARIANT* variant)
2258 {
2259         variant->vt = VT_UI4;
2260         variant->ulVal = 314;
2261
2262         return 0;
2263 }
2264
2265 STDCALL int
2266 mono_test_marshal_variant_out_long(VARIANT* variant)
2267 {
2268         variant->vt = VT_I8;
2269         variant->llVal = 314;
2270
2271         return 0;
2272 }
2273
2274 STDCALL int
2275 mono_test_marshal_variant_out_ulong(VARIANT* variant)
2276 {
2277         variant->vt = VT_UI8;
2278         variant->ullVal = 314;
2279
2280         return 0;
2281 }
2282
2283 STDCALL int
2284 mono_test_marshal_variant_out_float(VARIANT* variant)
2285 {
2286         variant->vt = VT_R4;
2287         variant->fltVal = 3.14;
2288
2289         return 0;
2290 }
2291
2292 STDCALL int
2293 mono_test_marshal_variant_out_double(VARIANT* variant)
2294 {
2295         variant->vt = VT_R8;
2296         variant->dblVal = 3.14;
2297
2298         return 0;
2299 }
2300
2301 STDCALL int
2302 mono_test_marshal_variant_out_bstr(VARIANT* variant)
2303 {
2304         variant->vt = VT_BSTR;
2305         variant->bstrVal = SysAllocString(L"PI");
2306
2307         return 0;
2308 }
2309
2310 STDCALL int
2311 mono_test_marshal_variant_out_bool_true (VARIANT* variant)
2312 {
2313         variant->vt = VT_BOOL;
2314         variant->boolVal = VARIANT_TRUE;
2315
2316         return 0;
2317 }
2318
2319 STDCALL int
2320 mono_test_marshal_variant_out_bool_false (VARIANT* variant)
2321 {
2322         variant->vt = VT_BOOL;
2323         variant->boolVal = VARIANT_FALSE;
2324
2325         return 0;
2326 }
2327
2328 typedef int (STDCALL *VarFunc) (int vt, VARIANT variant);
2329 typedef int (STDCALL *VarRefFunc) (int vt, VARIANT* variant);
2330
2331 STDCALL int
2332 mono_test_marshal_variant_in_sbyte_unmanaged(VarFunc func)
2333 {
2334         VARIANT vt;
2335         vt.vt = VT_I1;
2336         vt.cVal = -100;
2337         return func (VT_I1, vt);
2338 }
2339
2340 STDCALL int
2341 mono_test_marshal_variant_in_byte_unmanaged(VarFunc func)
2342 {
2343         VARIANT vt;
2344         vt.vt = VT_UI1;
2345         vt.bVal = 100;
2346         return func (VT_UI1, vt);
2347 }
2348
2349 STDCALL int
2350 mono_test_marshal_variant_in_short_unmanaged(VarFunc func)
2351 {
2352         VARIANT vt;
2353         vt.vt = VT_I2;
2354         vt.iVal = -100;
2355         return func (VT_I2, vt);
2356 }
2357
2358 STDCALL int
2359 mono_test_marshal_variant_in_ushort_unmanaged(VarFunc func)
2360 {
2361         VARIANT vt;
2362         vt.vt = VT_UI2;
2363         vt.uiVal = 100;
2364         return func (VT_UI2, vt);
2365 }
2366
2367 STDCALL int
2368 mono_test_marshal_variant_in_int_unmanaged(VarFunc func)
2369 {
2370         VARIANT vt;
2371         vt.vt = VT_I4;
2372         vt.lVal = -100;
2373         return func (VT_I4, vt);
2374 }
2375
2376 STDCALL int
2377 mono_test_marshal_variant_in_uint_unmanaged(VarFunc func)
2378 {
2379         VARIANT vt;
2380         vt.vt = VT_UI4;
2381         vt.ulVal = 100;
2382         return func (VT_UI4, vt);
2383 }
2384
2385 STDCALL int
2386 mono_test_marshal_variant_in_long_unmanaged(VarFunc func)
2387 {
2388         VARIANT vt;
2389         vt.vt = VT_I8;
2390         vt.llVal = -100;
2391         return func (VT_I8, vt);
2392 }
2393
2394 STDCALL int
2395 mono_test_marshal_variant_in_ulong_unmanaged(VarFunc func)
2396 {
2397         VARIANT vt;
2398         vt.vt = VT_UI8;
2399         vt.ullVal = 100;
2400         return func (VT_UI8, vt);
2401 }
2402
2403 STDCALL int
2404 mono_test_marshal_variant_in_float_unmanaged(VarFunc func)
2405 {
2406         VARIANT vt;
2407         vt.vt = VT_R4;
2408         vt.fltVal = 3.14;
2409         return func (VT_R4, vt);
2410 }
2411
2412 STDCALL int
2413 mono_test_marshal_variant_in_double_unmanaged(VarFunc func)
2414 {
2415         VARIANT vt;
2416         vt.vt = VT_R8;
2417         vt.dblVal = 3.14;
2418         return func (VT_R8, vt);
2419 }
2420
2421 STDCALL int
2422 mono_test_marshal_variant_in_bstr_unmanaged(VarFunc func)
2423 {
2424         VARIANT vt;
2425         vt.vt = VT_BSTR;
2426         vt.bstrVal = SysAllocString(L"PI");
2427         return func (VT_BSTR, vt);
2428 }
2429
2430 STDCALL int
2431 mono_test_marshal_variant_in_bool_true_unmanaged(VarFunc func)
2432 {
2433         VARIANT vt;
2434         vt.vt = VT_BOOL;
2435         vt.boolVal = VARIANT_TRUE;
2436         return func (VT_BOOL, vt);
2437 }
2438
2439 STDCALL int
2440 mono_test_marshal_variant_in_bool_false_unmanaged(VarFunc func)
2441 {
2442         VARIANT vt;
2443         vt.vt = VT_BOOL;
2444         vt.boolVal = VARIANT_FALSE;
2445         return func (VT_BOOL, vt);
2446 }
2447
2448 STDCALL int
2449 mono_test_marshal_variant_out_sbyte_unmanaged(VarRefFunc func)
2450 {
2451         VARIANT vt;
2452         VariantInit (&vt);
2453         func (VT_I1, &vt);
2454         if (vt.vt == VT_I1 && vt.cVal == -100)
2455                 return 0;
2456         return 1;
2457 }
2458
2459 STDCALL int
2460 mono_test_marshal_variant_out_byte_unmanaged(VarRefFunc func)
2461 {
2462         VARIANT vt;
2463         VariantInit (&vt);
2464         func (VT_UI1, &vt);
2465         if (vt.vt == VT_UI1 && vt.bVal == 100)
2466                 return 0;
2467         return 1;
2468 }
2469
2470 STDCALL int
2471 mono_test_marshal_variant_out_short_unmanaged(VarRefFunc func)
2472 {
2473         VARIANT vt;
2474         VariantInit (&vt);
2475         func (VT_I2, &vt);
2476         if (vt.vt == VT_I2 && vt.iVal == -100)
2477                 return 0;
2478         return 1;
2479 }
2480
2481 STDCALL int
2482 mono_test_marshal_variant_out_ushort_unmanaged(VarRefFunc func)
2483 {
2484         VARIANT vt;
2485         VariantInit (&vt);
2486         func (VT_UI2, &vt);
2487         if (vt.vt == VT_UI2 && vt.uiVal == 100)
2488                 return 0;
2489         return 1;
2490 }
2491
2492 STDCALL int
2493 mono_test_marshal_variant_out_int_unmanaged(VarRefFunc func)
2494 {
2495         VARIANT vt;
2496         VariantInit (&vt);
2497         func (VT_I4, &vt);
2498         if (vt.vt == VT_I4 && vt.lVal == -100)
2499                 return 0;
2500         return 1;
2501 }
2502
2503 STDCALL int
2504 mono_test_marshal_variant_out_uint_unmanaged(VarRefFunc func)
2505 {
2506         VARIANT vt;
2507         VariantInit (&vt);
2508         func (VT_UI4, &vt);
2509         if (vt.vt == VT_UI4 && vt.ulVal == 100)
2510                 return 0;
2511         return 1;
2512 }
2513
2514 STDCALL int
2515 mono_test_marshal_variant_out_long_unmanaged(VarRefFunc func)
2516 {
2517         VARIANT vt;
2518         VariantInit (&vt);
2519         func (VT_I8, &vt);
2520         if (vt.vt == VT_I8 && vt.llVal == -100)
2521                 return 0;
2522         return 1;
2523 }
2524
2525 STDCALL int
2526 mono_test_marshal_variant_out_ulong_unmanaged(VarRefFunc func)
2527 {
2528         VARIANT vt;
2529         VariantInit (&vt);
2530         func (VT_UI8, &vt);
2531         if (vt.vt == VT_UI8 && vt.ullVal == 100)
2532                 return 0;
2533         return 1;
2534 }
2535
2536 STDCALL int
2537 mono_test_marshal_variant_out_float_unmanaged(VarRefFunc func)
2538 {
2539         VARIANT vt;
2540         VariantInit (&vt);
2541         func (VT_R4, &vt);
2542         if (vt.vt == VT_R4 && fabs (vt.fltVal - 3.14f) < 1e-10)
2543                 return 0;
2544         return 1;
2545 }
2546
2547 STDCALL int
2548 mono_test_marshal_variant_out_double_unmanaged(VarRefFunc func)
2549 {
2550         VARIANT vt;
2551         VariantInit (&vt);
2552         func (VT_R8, &vt);
2553         if (vt.vt == VT_R8 && fabs (vt.dblVal - 3.14) < 1e-10)
2554                 return 0;
2555         return 1;
2556 }
2557
2558 STDCALL int
2559 mono_test_marshal_variant_out_bstr_unmanaged(VarRefFunc func)
2560 {
2561         VARIANT vt;
2562         VariantInit (&vt);
2563         func (VT_BSTR, &vt);
2564         if (vt.vt == VT_BSTR && !wcscmp(vt.bstrVal, L"PI"))
2565                 return 0;
2566         return 1;
2567 }
2568
2569 STDCALL int
2570 mono_test_marshal_variant_out_bool_true_unmanaged(VarRefFunc func)
2571 {
2572         VARIANT vt;
2573         VariantInit (&vt);
2574         func (VT_BOOL, &vt);
2575         if (vt.vt == VT_BOOL && vt.boolVal == VARIANT_TRUE)
2576                 return 0;
2577         return 1;
2578 }
2579
2580 STDCALL int
2581 mono_test_marshal_variant_out_bool_false_unmanaged(VarRefFunc func)
2582 {
2583         VARIANT vt;
2584         VariantInit (&vt);
2585         func (VT_BOOL, &vt);
2586         if (vt.vt == VT_BOOL && vt.boolVal == VARIANT_TRUE)
2587                 return 0;
2588         return 1;
2589 }
2590
2591 typedef struct MonoComObject MonoComObject;
2592
2593 typedef struct
2594 {
2595         int (STDCALL *QueryInterface)(MonoComObject* pUnk, gpointer riid, gpointer* ppv);
2596         int (STDCALL *AddRef)(MonoComObject* pUnk);
2597         int (STDCALL *Release)(MonoComObject* pUnk);
2598         int (STDCALL *get_ITest)(MonoComObject* pUnk, MonoComObject* *ppUnk);
2599         int (STDCALL *SByteIn)(MonoComObject* pUnk, char a);
2600         int (STDCALL *ByteIn)(MonoComObject* pUnk, unsigned char a);
2601         int (STDCALL *ShortIn)(MonoComObject* pUnk, short a);
2602         int (STDCALL *UShortIn)(MonoComObject* pUnk, unsigned short a);
2603         int (STDCALL *IntIn)(MonoComObject* pUnk, int a);
2604         int (STDCALL *UIntIn)(MonoComObject* pUnk, unsigned int a);
2605         int (STDCALL *LongIn)(MonoComObject* pUnk, LONGLONG a);
2606         int (STDCALL *ULongIn)(MonoComObject* pUnk, ULONGLONG a);
2607         int (STDCALL *FloatIn)(MonoComObject* pUnk, float a);
2608         int (STDCALL *DoubleIn)(MonoComObject* pUnk, double a);
2609         int (STDCALL *ITestIn)(MonoComObject* pUnk, MonoComObject* pUnk2);
2610         int (STDCALL *ITestOut)(MonoComObject* pUnk, MonoComObject* *ppUnk);
2611 } MonoIUnknown;
2612
2613 struct MonoComObject
2614 {
2615         MonoIUnknown* vtbl;
2616         int m_ref;
2617 };
2618
2619 DEFINE_GUID(IID_ITest, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);
2620 DEFINE_GUID(IID_IMonoUnknown, 0, 0, 0, 0xC0, 0, 0, 0, 0, 0, 0, 0x46);
2621 DEFINE_GUID(IID_IMonoDispatch, 0x00020400, 0, 0, 0xC0, 0, 0, 0, 0, 0, 0, 0x46);
2622
2623 int STDCALL MonoQueryInterface(MonoComObject* pUnk, gpointer riid, gpointer* ppv)
2624 {
2625         *ppv = NULL;
2626         if (!memcmp(riid, &IID_IMonoUnknown, sizeof(GUID))) {
2627                 *ppv = pUnk;
2628                 return S_OK;
2629         }
2630         else if (!memcmp(riid, &IID_ITest, sizeof(GUID))) {
2631                 *ppv = pUnk;
2632                 return S_OK;
2633         }
2634         else if (!memcmp(riid, &IID_IMonoDispatch, sizeof(GUID))) {
2635                 *ppv = pUnk;
2636                 return S_OK;
2637         }
2638         return E_NOINTERFACE;
2639 }
2640
2641 int STDCALL MonoAddRef(MonoComObject* pUnk)
2642 {
2643         return ++(pUnk->m_ref);
2644 }
2645
2646 int STDCALL MonoRelease(MonoComObject* pUnk)
2647 {
2648         return --(pUnk->m_ref);
2649 }
2650
2651 int STDCALL SByteIn(MonoComObject* pUnk, char a)
2652 {
2653         return S_OK;
2654 }
2655
2656 int STDCALL ByteIn(MonoComObject* pUnk, unsigned char a)
2657 {
2658         return S_OK;
2659 }
2660
2661 int STDCALL ShortIn(MonoComObject* pUnk, short a)
2662 {
2663         return S_OK;
2664 }
2665
2666 int STDCALL UShortIn(MonoComObject* pUnk, unsigned short a)
2667 {
2668         return S_OK;
2669 }
2670
2671 int STDCALL IntIn(MonoComObject* pUnk, int a)
2672 {
2673         return S_OK;
2674 }
2675
2676 int STDCALL UIntIn(MonoComObject* pUnk, unsigned int a)
2677 {
2678         return S_OK;
2679 }
2680
2681 int STDCALL LongIn(MonoComObject* pUnk, LONGLONG a)
2682 {
2683         return S_OK;
2684 }
2685
2686 int STDCALL ULongIn(MonoComObject* pUnk, ULONGLONG a)
2687 {
2688         return S_OK;
2689 }
2690
2691 int STDCALL FloatIn(MonoComObject* pUnk, float a)
2692 {
2693         return S_OK;
2694 }
2695
2696 int STDCALL DoubleIn(MonoComObject* pUnk, double a)
2697 {
2698         return S_OK;
2699 }
2700
2701 int STDCALL ITestIn(MonoComObject* pUnk, MonoComObject *pUnk2)
2702 {
2703         return S_OK;
2704 }
2705
2706 int STDCALL ITestOut(MonoComObject* pUnk, MonoComObject* *ppUnk)
2707 {
2708         return S_OK;
2709 }
2710
2711 int STDCALL get_ITest(MonoComObject* pUnk, MonoComObject* *ppUnk)
2712 {
2713         return S_OK;
2714 }
2715
2716 static void create_com_object (MonoComObject** pOut)
2717 {
2718         *pOut = g_new0 (MonoComObject, 1);
2719         (*pOut)->vtbl = g_new0 (MonoIUnknown, 1);
2720
2721         (*pOut)->m_ref = 1;
2722         (*pOut)->vtbl->QueryInterface = MonoQueryInterface;
2723         (*pOut)->vtbl->AddRef = MonoAddRef;
2724         (*pOut)->vtbl->Release = MonoRelease;
2725         (*pOut)->vtbl->SByteIn = SByteIn;
2726         (*pOut)->vtbl->ByteIn = ByteIn;
2727         (*pOut)->vtbl->ShortIn = ShortIn;
2728         (*pOut)->vtbl->UShortIn = UShortIn;
2729         (*pOut)->vtbl->IntIn = IntIn;
2730         (*pOut)->vtbl->UIntIn = UIntIn;
2731         (*pOut)->vtbl->LongIn = LongIn;
2732         (*pOut)->vtbl->ULongIn = ULongIn;
2733         (*pOut)->vtbl->FloatIn = FloatIn;
2734         (*pOut)->vtbl->DoubleIn = DoubleIn;
2735         (*pOut)->vtbl->ITestIn = ITestIn;
2736         (*pOut)->vtbl->ITestOut = ITestOut;
2737         (*pOut)->vtbl->get_ITest = get_ITest;
2738 }
2739
2740 static MonoComObject* same_object = NULL;
2741
2742 STDCALL int
2743 mono_test_marshal_com_object_create(MonoComObject* *pUnk)
2744 {
2745         create_com_object (pUnk);
2746
2747         if (!same_object)
2748                 same_object = *pUnk;
2749
2750         return 0;
2751 }
2752
2753 STDCALL int
2754 mono_test_marshal_com_object_same(MonoComObject* *pUnk)
2755 {
2756         *pUnk = same_object;
2757
2758         return 0;
2759 }
2760
2761 STDCALL int
2762 mono_test_marshal_com_object_destroy(MonoComObject *pUnk)
2763 {
2764         int ref = --(pUnk->m_ref);
2765         g_free(pUnk->vtbl);
2766         g_free(pUnk);
2767
2768         return ref;
2769 }
2770
2771 STDCALL int
2772 mono_test_marshal_com_object_ref_count(MonoComObject *pUnk)
2773 {
2774         return pUnk->m_ref;
2775 }
2776
2777 STDCALL int
2778 mono_test_marshal_ccw_itest (MonoComObject *pUnk)
2779 {
2780         int hr = 0;
2781         MonoComObject* pTest;
2782
2783         if (!pUnk)
2784                 return 1;
2785
2786         hr = pUnk->vtbl->SByteIn (pUnk, -100);
2787         if (hr != 0)
2788                 return 2;
2789         hr = pUnk->vtbl->ByteIn (pUnk, 100);
2790         if (hr != 0)
2791                 return 3;
2792         hr = pUnk->vtbl->ShortIn (pUnk, -100);
2793         if (hr != 0)
2794                 return 4;
2795         hr = pUnk->vtbl->UShortIn (pUnk, 100);
2796         if (hr != 0)
2797                 return 5;
2798         hr = pUnk->vtbl->IntIn (pUnk, -100);
2799         if (hr != 0)
2800                 return 6;
2801         hr = pUnk->vtbl->UIntIn (pUnk, 100);
2802         if (hr != 0)
2803                 return 7;
2804         hr = pUnk->vtbl->LongIn (pUnk, -100);
2805         if (hr != 0)
2806                 return 8;
2807         hr = pUnk->vtbl->ULongIn (pUnk, 100);
2808         if (hr != 0)
2809                 return 9;
2810         hr = pUnk->vtbl->FloatIn (pUnk, 3.14f);
2811         if (hr != 0)
2812                 return 10;
2813         hr = pUnk->vtbl->DoubleIn (pUnk, 3.14);
2814         if (hr != 0)
2815                 return 11;
2816         hr = pUnk->vtbl->ITestIn (pUnk, pUnk);
2817         if (hr != 0)
2818                 return 12;
2819         hr = pUnk->vtbl->ITestOut (pUnk, &pTest);
2820         if (hr != 0)
2821                 return 13;
2822
2823         return 0;
2824 }
2825
2826
2827 #endif //NOT_YET