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