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