2009-06-12 Bill Holmes <billholmes54@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 <gmodule.h>
6 #include <errno.h>
7 #include <time.h>
8 #include <math.h>
9
10 #ifdef WIN32
11 #include <windows.h>
12 #include "initguid.h"
13 #endif
14
15 #ifdef WIN32
16 #define STDCALL __stdcall
17 #else
18 #define STDCALL
19 #endif
20
21 #ifdef __GNUC__
22 #pragma GCC diagnostic ignored "-Wmissing-prototypes"
23 #endif
24
25 #ifdef WIN32
26 extern __declspec(dllimport) void __stdcall CoTaskMemFree(void *ptr);
27 #endif
28
29 typedef int (STDCALL *SimpleDelegate) (int a);
30
31 #if defined(WIN32) && defined (_MSC_VER)
32 #define LIBTEST_API __declspec(dllexport)
33 #else 
34 #define LIBTEST_API
35 #endif
36
37 static void marshal_free (void *ptr)
38 {
39 #ifdef WIN32
40         CoTaskMemFree (ptr);
41 #else
42         g_free (ptr);
43 #endif
44 }
45
46 static void* marshal_alloc (gsize size)
47 {
48 #ifdef WIN32
49         return CoTaskMemAlloc (size);
50 #else
51         return g_malloc (size);
52 #endif
53 }
54
55 LIBTEST_API unsigned short* STDCALL
56 test_lpwstr_marshal (unsigned short* chars, long length)
57 {
58         int i = 0;
59         unsigned short *res;
60
61         res = marshal_alloc (2 * (length + 1));
62
63         // printf("test_lpwstr_marshal()\n");
64         
65         while ( i < length ) {
66                 // printf("X|%u|\n", chars[i]);
67                 res [i] = chars[i];
68                 i++;
69         }
70
71         res [i] = 0;
72
73         return res;
74 }
75
76
77 LIBTEST_API void STDCALL
78 test_lpwstr_marshal_out (unsigned short** chars)
79 {
80         int i = 0;
81         const char abc[] = "ABC";
82         glong len = strlen(abc);
83
84         *chars = marshal_alloc (2 * (len + 1));
85         
86         while ( i < len ) {
87                 (*chars) [i] = abc[i];
88                 i++;
89         }
90
91         (*chars) [i] = 0;
92 }
93
94 typedef struct {
95         int b;
96         int a;
97         int c;
98 } union_test_1_type;
99
100 LIBTEST_API int STDCALL  
101 mono_union_test_1 (union_test_1_type u1) {
102         // printf ("Got values %d %d %d\n", u1.b, u1.a, u1.c);
103         return u1.a + u1.b + u1.c;
104 }
105
106 LIBTEST_API int STDCALL  
107 mono_return_int (int a) {
108         // printf ("Got value %d\n", a);
109         return a;
110 }
111
112 LIBTEST_API float STDCALL  
113 mono_test_marshal_pass_return_float (float f) {
114         return f + 1.0;
115 }
116
117 struct ss
118 {
119         int i;
120 };
121
122 LIBTEST_API int STDCALL 
123 mono_return_int_ss (struct ss a) {
124         // printf ("Got value %d\n", a.i);
125         return a.i;
126 }
127
128 LIBTEST_API struct ss STDCALL
129 mono_return_ss (struct ss a) {
130         // printf ("Got value %d\n", a.i);
131         a.i++;
132         return a;
133 }
134
135 struct sc1
136 {
137         char c[1];
138 };
139
140 LIBTEST_API struct sc1 STDCALL
141 mono_return_sc1 (struct sc1 a) {
142         // printf ("Got value %d\n", a.c[0]);
143         a.c[0]++;
144         return a;
145 }
146
147
148 struct sc3
149 {
150         char c[3];
151 };
152
153 LIBTEST_API struct sc3 STDCALL 
154 mono_return_sc3 (struct sc3 a) {
155         // printf ("Got values %d %d %d\n", a.c[0], a.c[1], a.c[2]);
156         a.c[0]++;
157         a.c[1] += 2;
158         a.c[2] += 3;
159         return a;
160 }
161
162 struct sc5
163 {
164         char c[5];
165 };
166
167 LIBTEST_API struct sc5 STDCALL 
168 mono_return_sc5 (struct sc5 a) {
169         // printf ("Got values %d %d %d %d %d\n", a.c[0], a.c[1], a.c[2], a.c[3], a.c[4]);
170         a.c[0]++;
171         a.c[1] += 2;
172         a.c[2] += 3;
173         a.c[3] += 4;
174         a.c[4] += 5;
175         return a;
176 }
177
178 union su
179 {
180         int i1;
181         int i2;
182 };
183
184 LIBTEST_API int STDCALL  
185 mono_return_int_su (union su a) {
186         // printf ("Got value %d\n", a.i1);
187         return a.i1;
188 }
189
190 LIBTEST_API int STDCALL  
191 mono_test_many_int_arguments (int a, int b, int c, int d, int e,
192                                                           int f, int g, int h, int i, int j);
193 LIBTEST_API short STDCALL 
194 mono_test_many_short_arguments (short a, short b, short c, short d, short e,
195                                                                 short f, short g, short h, short i, short j);
196 LIBTEST_API char STDCALL 
197 mono_test_many_char_arguments (char a, char b, char c, char d, char e,
198                                                            char f, char g, char h, char i, char j);
199
200 LIBTEST_API int STDCALL 
201 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)
202 {
203         return a + b + c + d + e + f + g + h + i + j;
204 }
205
206 LIBTEST_API short STDCALL 
207 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)
208 {
209         return a + b + c + d + e + f + g + h + i + j;
210 }
211
212 LIBTEST_API char STDCALL 
213 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)
214 {
215         return a + b + c + d + e + f + g + h + i + j;
216 }
217
218 LIBTEST_API float STDCALL 
219 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)
220 {
221         return a + b + c + d + e + f + g + h + i + j;
222 }
223
224 LIBTEST_API double STDCALL 
225 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)
226 {
227         return a + b + c + d + e + f + g + h + i + j;
228 }
229
230 LIBTEST_API double STDCALL 
231 mono_test_split_double_arguments (double a, double b, float c, double d, double e)
232 {
233         return a + b + c + d + e;
234 }
235
236 LIBTEST_API int STDCALL 
237 mono_test_puts_static (char *s)
238 {
239         // printf ("TEST %s\n", s);
240         return 1;
241 }
242
243 typedef int (STDCALL *SimpleDelegate3) (int a, int b);
244
245 LIBTEST_API int STDCALL 
246 mono_invoke_delegate (SimpleDelegate3 delegate)
247 {
248         int res;
249
250         // printf ("start invoke %p\n", delegate);
251
252         res = delegate (2, 3);
253
254         // printf ("end invoke\n");
255
256         return res;
257 }
258
259 LIBTEST_API int STDCALL
260 mono_invoke_simple_delegate (SimpleDelegate d)
261 {
262         return d (4);
263 }
264
265 LIBTEST_API int STDCALL  
266 mono_test_marshal_char (short a1)
267 {
268         if (a1 == 'a')
269                 return 0;
270         
271         return 1;
272 }
273
274 LIBTEST_API void STDCALL
275 mono_test_marshal_char_array (gunichar2 *s)
276 {
277         const char m[] = "abcdef";
278         gunichar2* s2;
279         glong len;
280
281         s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
282         
283         len = (len * 2) + 2;
284         memcpy (s, s2, len);
285
286         g_free (s2);
287 }
288
289 LIBTEST_API int STDCALL 
290 mono_test_empty_pinvoke (int i)
291 {
292         return i;
293 }
294
295 LIBTEST_API int STDCALL  
296 mono_test_marshal_bool_byref (int a, int *b, int c)
297 {
298     int res = *b;
299
300         *b = 1;
301
302         return res;
303 }
304
305 LIBTEST_API int STDCALL 
306 mono_test_marshal_bool_in_as_I1_U1 (char bTrue, char bFalse)
307 {
308         if (!bTrue)
309                 return 1;
310         if (bFalse)
311                 return 2;
312         return 0;
313 }
314
315 LIBTEST_API int STDCALL 
316 mono_test_marshal_bool_out_as_I1_U1 (char* bTrue, char* bFalse)
317 {
318         if (!bTrue || !bFalse)
319                 return 3;
320
321         *bTrue = 1;
322         *bFalse = 0;
323
324         return 0;
325 }
326
327 LIBTEST_API int STDCALL 
328 mono_test_marshal_bool_ref_as_I1_U1 (char* bTrue, char* bFalse)
329 {
330         if (!bTrue || !bFalse)
331                 return 4;
332
333         if (!(*bTrue))
334                 return 5;
335         if (*bFalse)
336                 return 6;
337
338         *bFalse = 1;
339         *bTrue = 0;
340
341         return 0;
342 }
343
344 LIBTEST_API int STDCALL  
345 mono_test_marshal_array (int *a1)
346 {
347         int i, sum = 0;
348
349         for (i = 0; i < 50; i++)
350                 sum += a1 [i];
351         
352         return sum;
353 }
354
355 LIBTEST_API int STDCALL  
356 mono_test_marshal_inout_array (int *a1)
357 {
358         int i, sum = 0;
359
360         for (i = 0; i < 50; i++) {
361                 sum += a1 [i];
362                 a1 [i] = 50 - a1 [i];
363         }
364         
365         return sum;
366 }
367
368 LIBTEST_API int STDCALL  
369 mono_test_marshal_out_array (int *a1)
370 {
371         int i;
372
373         for (i = 0; i < 50; i++) {
374                 a1 [i] = i;
375         }
376         
377         return 0;
378 }
379
380 LIBTEST_API int STDCALL  
381 mono_test_marshal_inout_nonblittable_array (gunichar2 *a1)
382 {
383         int i, sum = 0;
384
385         for (i = 0; i < 10; i++) {
386                 a1 [i] = 'F';
387         }
388         
389         return sum;
390 }
391
392 typedef struct {
393         int a;
394         int b;
395         int c;
396         const char *d;
397         gunichar2 *d2;
398 } simplestruct;
399
400 typedef struct {
401         double x;
402         double y;
403 } point;
404
405 LIBTEST_API simplestruct STDCALL 
406 mono_test_return_vtype (int i)
407 {
408         simplestruct res;
409         static gunichar2 test2 [] = { 'T', 'E', 'S', 'T', '2', 0 };
410
411         res.a = 0;
412         res.b = 1;
413         res.c = 0;
414         res.d = "TEST";
415         res.d2 = test2;
416
417         return res;
418 }
419
420 LIBTEST_API void STDCALL
421 mono_test_delegate_struct (void)
422 {
423         // printf ("TEST\n");
424 }
425
426 typedef char* (STDCALL *ReturnStringDelegate) (const char *s);
427
428 LIBTEST_API char * STDCALL 
429 mono_test_return_string (ReturnStringDelegate func)
430 {
431         char *res;
432
433         // printf ("mono_test_return_string\n");
434
435         res = func ("TEST");
436         marshal_free (res);
437
438         // printf ("got string: %s\n", res);
439         return g_strdup ("12345");
440 }
441
442 typedef int (STDCALL *RefVTypeDelegate) (int a, simplestruct *ss, int b);
443
444 LIBTEST_API int STDCALL 
445 mono_test_ref_vtype (int a, simplestruct *ss, int b, RefVTypeDelegate func)
446 {
447         if (a == 1 && b == 2 && ss->a == 0 && ss->b == 1 && ss->c == 0 &&
448             !strcmp (ss->d, "TEST1")) {
449                 ss->a = 1;
450                 ss->b = 0;
451                 ss->c = 1;
452                 ss->d = "TEST2";
453
454                 return func (a, ss, b);
455         }
456
457         return 1;
458 }
459
460 typedef int (STDCALL *OutVTypeDelegate) (int a, simplestruct *ss, int b);
461
462 LIBTEST_API int STDCALL 
463 mono_test_marshal_out_struct (int a, simplestruct *ss, int b, OutVTypeDelegate func)
464 {
465         /* Check that the input pointer is ignored */
466         ss->d = (gpointer)0x12345678;
467
468         func (a, ss, b);
469
470         if (ss->a && ss->b && ss->c && !strcmp (ss->d, "TEST3"))
471                 return 0;
472         else
473                 return 1;
474 }
475
476 typedef struct {
477         int a;
478         SimpleDelegate func, func2, func3;
479 } DelegateStruct;
480
481 LIBTEST_API DelegateStruct STDCALL 
482 mono_test_marshal_delegate_struct (DelegateStruct ds)
483 {
484         DelegateStruct res;
485
486         res.a = ds.func (ds.a) + ds.func2 (ds.a) + (ds.func3 == NULL ? 0 : 1);
487         res.func = ds.func;
488         res.func2 = ds.func2;
489         res.func3 = NULL;
490
491         return res;
492 }
493
494 LIBTEST_API int STDCALL  
495 mono_test_marshal_struct (simplestruct ss)
496 {
497         if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
498             !strcmp (ss.d, "TEST"))
499                 return 0;
500
501         return 1;
502 }
503
504 LIBTEST_API int STDCALL 
505 mono_test_marshal_byref_struct (simplestruct *ss, int a, int b, int c, char *d)
506 {
507         gboolean res = (ss->a == a && ss->b == b && ss->c == c && strcmp (ss->d, d) == 0);
508
509         marshal_free ((char*)ss->d);
510
511         ss->a = !ss->a;
512         ss->b = !ss->b;
513         ss->c = !ss->c;
514         ss->d = g_strdup ("DEF");
515
516         return res ? 0 : 1;
517 }
518
519 typedef struct {
520         int a;
521         int b;
522         int c;
523         char *d;
524         unsigned char e;
525         double f;
526         unsigned char g;
527         guint64 h;
528 } simplestruct2;
529
530 LIBTEST_API int STDCALL 
531 mono_test_marshal_struct2 (simplestruct2 ss)
532 {
533         if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
534             !strcmp (ss.d, "TEST") && 
535             ss.e == 99 && ss.f == 1.5 && ss.g == 42 && ss.h == (guint64)123)
536                 return 0;
537
538         return 1;
539 }
540
541 /* on HP some of the struct should be on the stack and not in registers */
542 LIBTEST_API int STDCALL 
543 mono_test_marshal_struct2_2 (int i, int j, int k, simplestruct2 ss)
544 {
545         if (i != 10 || j != 11 || k != 12)
546                 return 1;
547         if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
548             !strcmp (ss.d, "TEST") && 
549             ss.e == 99 && ss.f == 1.5 && ss.g == 42 && ss.h == (guint64)123)
550                 return 0;
551
552         return 1;
553 }
554
555 LIBTEST_API int STDCALL  
556 mono_test_marshal_lpstruct (simplestruct *ss)
557 {
558         if (ss->a == 0 && ss->b == 1 && ss->c == 0 &&
559             !strcmp (ss->d, "TEST"))
560                 return 0;
561
562         return 1;
563 }
564
565 LIBTEST_API int STDCALL  
566 mono_test_marshal_lpstruct_blittable (point *p)
567 {
568         if (p->x == 1.0 && p->y == 2.0)
569                 return 0;
570         else
571                 return 1;
572 }
573
574 LIBTEST_API int STDCALL 
575 mono_test_marshal_struct_array (simplestruct2 *ss)
576 {
577         if (! (ss[0].a == 0 && ss[0].b == 1 && ss[0].c == 0 &&
578                    !strcmp (ss[0].d, "TEST") && 
579                    ss[0].e == 99 && ss[0].f == 1.5 && ss[0].g == 42 && ss[0].h == (guint64)123))
580                 return 1;
581
582         if (! (ss[1].a == 0 && ss[1].b == 0 && ss[1].c == 0 &&
583                    !strcmp (ss[1].d, "TEST2") && 
584                    ss[1].e == 100 && ss[1].f == 2.5 && ss[1].g == 43 && ss[1].h == (guint64)124))
585                 return 1;
586
587         return 0;
588 }
589
590 typedef struct long_align_struct {
591         gint32 a;
592         gint64 b;
593         gint64 c;
594 } long_align_struct;
595
596 LIBTEST_API int STDCALL 
597 mono_test_marshal_long_align_struct_array (long_align_struct *ss)
598 {
599         return ss[0].a + ss[0].b + ss[0].c + ss[1].a + ss[1].b + ss[1].c;
600 }
601
602 LIBTEST_API simplestruct2 * STDCALL 
603 mono_test_marshal_class (int i, int j, int k, simplestruct2 *ss, int l)
604 {
605         simplestruct2 *res;
606
607         if (!ss)
608                 return NULL;
609
610         if (i != 10 || j != 11 || k != 12 || l != 14)
611                 return NULL;
612         if (! (ss->a == 0 && ss->b == 1 && ss->c == 0 &&
613                    !strcmp (ss->d, "TEST") && 
614                    ss->e == 99 && ss->f == 1.5 && ss->g == 42 && ss->h == (guint64)123))
615                 return NULL;
616
617         res = g_new0 (simplestruct2, 1);
618         memcpy (res, ss, sizeof (simplestruct2));
619         res->d = g_strdup ("TEST");
620         return res;
621 }
622
623 LIBTEST_API int STDCALL 
624 mono_test_marshal_byref_class (simplestruct2 **ssp)
625 {
626         simplestruct2 *ss = *ssp;
627         simplestruct2 *res;
628         
629         if (! (ss->a == 0 && ss->b == 1 && ss->c == 0 &&
630                    !strcmp (ss->d, "TEST") && 
631                    ss->e == 99 && ss->f == 1.5 && ss->g == 42 && ss->h == (guint64)123))
632                 return 1;
633
634         res = g_new0 (simplestruct2, 1);
635         memcpy (res, ss, sizeof (simplestruct2));
636         res->d = g_strdup ("TEST-RES");
637
638         *ssp = res;
639         return 0;
640 }
641
642 static void *
643 get_sp (void)
644 {
645         int i;
646         void *p;
647
648         /* Yes, this is correct, we are only trying to determine the value of the stack here */
649         p = &i;
650         return p;
651 }
652
653 LIBTEST_API int STDCALL 
654 reliable_delegate (int a)
655 {
656         return a;
657 }
658
659 /*
660  * Checks whether get_sp() works as expected. It doesn't work with gcc-2.95.3 on linux.
661  */
662 static gboolean
663 is_get_sp_reliable (void)
664 {
665         void *sp1, *sp2;
666
667         reliable_delegate(1);
668         sp1 = get_sp();
669         reliable_delegate(1);
670         sp2 = get_sp();
671         return sp1 == sp2;
672
673
674 LIBTEST_API int STDCALL 
675 mono_test_marshal_delegate (SimpleDelegate delegate)
676 {
677         void *sp1, *sp2;
678
679         /* Check that the delegate wrapper is stdcall */
680         delegate (2);
681         sp1 = get_sp ();
682         delegate (2);
683         sp2 = get_sp ();
684         if (is_get_sp_reliable())
685                 g_assert (sp1 == sp2);
686
687         return delegate (2);
688 }
689
690 static int STDCALL inc_cb (int i)
691 {
692         return i + 1;
693 }
694
695 LIBTEST_API int STDCALL 
696 mono_test_marshal_out_delegate (SimpleDelegate *delegate)
697 {
698         *delegate = inc_cb;
699
700         return 0;
701 }
702
703 LIBTEST_API SimpleDelegate STDCALL 
704 mono_test_marshal_return_delegate (SimpleDelegate delegate)
705 {
706         return delegate;
707 }
708
709 static int STDCALL
710 return_plus_one (int i)
711 {
712         return i + 1;
713 }
714
715 LIBTEST_API SimpleDelegate STDCALL 
716 mono_test_marshal_return_delegate_2 (void)
717 {
718         return return_plus_one;
719 }
720
721 typedef simplestruct (STDCALL *SimpleDelegate2) (simplestruct ss);
722
723 static gboolean
724 is_utf16_equals (gunichar2 *s1, const char *s2)
725 {
726         char *s;
727         int res;
728
729         s = g_utf16_to_utf8 (s1, -1, NULL, NULL, NULL);
730         res = strcmp (s, s2);
731         g_free (s);
732
733         return res == 0;
734 }
735
736 LIBTEST_API int STDCALL 
737 mono_test_marshal_delegate2 (SimpleDelegate2 delegate)
738 {
739         simplestruct ss, res;
740
741         ss.a = 0;
742         ss.b = 1;
743         ss.c = 0;
744         ss.d = "TEST";
745         ss.d2 = g_utf8_to_utf16 ("TEST2", -1, NULL, NULL, NULL); 
746
747         res = delegate (ss);
748         if (! (res.a && !res.b && res.c && !strcmp (res.d, "TEST-RES") && is_utf16_equals (res.d2, "TEST2-RES")))
749                 return 1;
750
751         return 0;
752 }
753
754 typedef simplestruct* (STDCALL *SimpleDelegate4) (simplestruct *ss);
755
756 LIBTEST_API int STDCALL 
757 mono_test_marshal_delegate4 (SimpleDelegate4 delegate)
758 {
759         simplestruct ss;
760         simplestruct *res;
761
762         ss.a = 0;
763         ss.b = 1;
764         ss.c = 0;
765         ss.d = "TEST";
766
767         /* Check argument */
768         res = delegate (&ss);
769         if (!res)
770                 return 1;
771
772         /* Check return value */
773         if (! (!res->a && res->b && !res->c && !strcmp (res->d, "TEST")))
774                 return 2;
775
776         /* Check NULL argument and NULL result */
777         res = delegate (NULL);
778         if (res)
779                 return 3;
780
781         return 0;
782 }
783
784 typedef int (STDCALL *SimpleDelegate5) (simplestruct **ss);
785
786 LIBTEST_API int STDCALL 
787 mono_test_marshal_delegate5 (SimpleDelegate5 delegate)
788 {
789         simplestruct ss;
790         int res;
791         simplestruct *ptr;
792
793         ss.a = 0;
794         ss.b = 1;
795         ss.c = 0;
796         ss.d = "TEST";
797
798         ptr = &ss;
799
800         res = delegate (&ptr);
801         if (res != 0)
802                 return 1;
803
804         if (!(ptr->a && !ptr->b && ptr->c && !strcmp (ptr->d, "RES")))
805                 return 2;
806
807         return 0;
808 }
809
810 LIBTEST_API int STDCALL 
811 mono_test_marshal_delegate6 (SimpleDelegate5 delegate)
812 {
813         int res;
814
815         res = delegate (NULL);
816
817         return 0;
818 }
819
820 typedef int (STDCALL *SimpleDelegate7) (simplestruct **ss);
821
822 LIBTEST_API int STDCALL 
823 mono_test_marshal_delegate7 (SimpleDelegate7 delegate)
824 {
825         int res;
826         simplestruct *ptr;
827
828         /* Check that the input pointer is ignored */
829         ptr = (gpointer)0x12345678;
830
831         res = delegate (&ptr);
832         if (res != 0)
833                 return 1;
834
835         if (!(ptr->a && !ptr->b && ptr->c && !strcmp (ptr->d, "RES")))
836                 return 2;
837
838         return 0;
839 }
840
841 typedef int (STDCALL *InOutByvalClassDelegate) (simplestruct *ss);
842
843 LIBTEST_API int STDCALL 
844 mono_test_marshal_inout_byval_class_delegate (InOutByvalClassDelegate delegate)
845 {
846         int res;
847         simplestruct ss;
848
849         ss.a = FALSE;
850         ss.b = TRUE;
851         ss.c = FALSE;
852         ss.d = g_strdup_printf ("%s", "FOO");
853
854         res = delegate (&ss);
855         if (res != 0)
856                 return 1;
857
858         if (!(ss.a && !ss.b && ss.c && !strcmp (ss.d, "RES")))
859                 return 2;
860
861         return 0;
862 }
863
864 typedef int (STDCALL *SimpleDelegate8) (gunichar2 *s);
865
866 LIBTEST_API int STDCALL 
867 mono_test_marshal_delegate8 (SimpleDelegate8 delegate, gunichar2 *s)
868 {
869         return delegate (s);
870 }
871
872 typedef int (STDCALL *return_int_fnt) (int i);
873 typedef int (STDCALL *SimpleDelegate9) (return_int_fnt d);
874
875 LIBTEST_API int STDCALL 
876 mono_test_marshal_delegate9 (SimpleDelegate9 delegate, gpointer ftn)
877 {
878         return delegate (ftn);
879 }
880
881 static int STDCALL 
882 return_self (int i)
883 {
884         return i;
885 }
886
887 LIBTEST_API int STDCALL 
888 mono_test_marshal_delegate10 (SimpleDelegate9 delegate)
889 {
890         return delegate (return_self);
891 }
892
893 typedef int (STDCALL *PrimitiveByrefDelegate) (int *i);
894
895 LIBTEST_API int STDCALL 
896 mono_test_marshal_primitive_byref_delegate (PrimitiveByrefDelegate delegate)
897 {
898         int i = 1;
899
900         int res = delegate (&i);
901         if (res != 0)
902                 return res;
903
904         if (i != 2)
905                 return 2;
906
907         return 0;
908 }
909
910 typedef int (STDCALL *return_int_delegate) (int i);
911
912 typedef return_int_delegate (STDCALL *ReturnDelegateDelegate) (void);
913
914 LIBTEST_API int STDCALL 
915 mono_test_marshal_return_delegate_delegate (ReturnDelegateDelegate d)
916 {
917         return (d ()) (55);
918 }
919
920 LIBTEST_API int STDCALL  
921 mono_test_marshal_stringbuilder (char *s, int n)
922 {
923         const char m[] = "This is my message.  Isn't it nice?";
924
925         if (strcmp (s, "ABCD") != 0)
926                 return 1;
927         strncpy(s, m, n);
928         s [n] = '\0';
929         return 0;
930 }
931
932 LIBTEST_API int STDCALL  
933 mono_test_marshal_stringbuilder_default (char *s, int n)
934 {
935         const char m[] = "This is my message.  Isn't it nice?";
936
937         strncpy(s, m, n);
938         s [n] = '\0';
939         return 0;
940 }
941
942 LIBTEST_API int STDCALL  
943 mono_test_marshal_stringbuilder_unicode (gunichar2 *s, int n)
944 {
945         const char m[] = "This is my message.  Isn't it nice?";
946         gunichar2* s2;
947         glong len;
948
949         s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
950         
951         len = (len * 2) + 2;
952         if (len > (n * 2))
953                 len = n * 2;
954         memcpy (s, s2, len);
955
956         g_free (s2);
957
958         return 0;
959 }
960
961 typedef struct {
962 #ifndef __GNUC__
963     char a;
964 #endif
965 } EmptyStruct;
966
967 LIBTEST_API int STDCALL 
968 mono_test_marshal_empty_string_array (char **array)
969 {
970         return (array == NULL) ? 0 : 1;
971 }
972
973 LIBTEST_API int STDCALL 
974 mono_test_marshal_string_array (char **array)
975 {
976         if (strcmp (array [0], "ABC"))
977                 return 1;
978         if (strcmp (array [1], "DEF"))
979                 return 2;
980
981         if (array [2] != NULL)
982                 return 3;
983
984         return 0;
985 }
986
987 LIBTEST_API int STDCALL 
988 mono_test_marshal_byref_string_array (char ***array)
989 {
990         if (*array == NULL)
991                 return 0;
992
993         if (strcmp ((*array) [0], "Alpha"))
994                 return 2;
995         if (strcmp ((*array) [1], "Beta"))
996                 return 2;
997         if (strcmp ((*array) [2], "Gamma"))
998                 return 2;
999
1000         return 1;
1001 }
1002
1003 LIBTEST_API int STDCALL 
1004 mono_test_marshal_stringbuilder_array (char **array)
1005 {
1006         if (strcmp (array [0], "ABC"))
1007                 return 1;
1008         if (strcmp (array [1], "DEF"))
1009                 return 2;
1010
1011         strcpy (array [0], "DEF");
1012         strcpy (array [1], "ABC");
1013
1014         return 0;
1015 }
1016
1017 LIBTEST_API int STDCALL 
1018 mono_test_marshal_unicode_string_array (gunichar2 **array, char **array2)
1019 {
1020         GError *error = NULL;
1021         char *s;
1022         
1023         s = g_utf16_to_utf8 (array [0], -1, NULL, NULL, &error);
1024         if (strcmp (s, "ABC")) {
1025                 g_free (s);
1026                 return 1;
1027         }
1028         else
1029                 g_free (s);
1030
1031         s = g_utf16_to_utf8 (array [1], -1, NULL, NULL, &error);
1032         if (strcmp (s, "DEF")) {
1033                 g_free (s);
1034                 return 2;
1035         }
1036         else
1037                 g_free (s);
1038
1039         if (strcmp (array2 [0], "ABC"))
1040                 return 3;
1041
1042         if (strcmp (array2 [1], "DEF")) 
1043                 return 4;
1044
1045         return 0;
1046 }
1047
1048 /* this does not work on Redhat gcc 2.96 */
1049 LIBTEST_API int STDCALL  
1050 mono_test_empty_struct (int a, EmptyStruct es, int b)
1051 {
1052         // printf ("mono_test_empty_struct %d %d\n", a, b);
1053
1054         // Intel icc on ia64 passes 'es' in 2 registers
1055 #if defined(__ia64) && defined(__INTEL_COMPILER)
1056         return 0;
1057 #else
1058         if (a == 1 && b == 2)
1059                 return 0;
1060         return 1;
1061 #endif
1062 }
1063
1064 typedef struct {
1065        char a[100];
1066 } ByValStrStruct;
1067
1068 LIBTEST_API ByValStrStruct * STDCALL 
1069 mono_test_byvalstr_gen (void)
1070 {
1071         ByValStrStruct *ret;
1072        
1073         ret = malloc(sizeof(ByValStrStruct));
1074         memset(ret, 'a', sizeof(ByValStrStruct)-1);
1075         ret->a[sizeof(ByValStrStruct)-1] = 0;
1076
1077         return ret;
1078 }
1079
1080 LIBTEST_API int STDCALL 
1081 mono_test_byvalstr_check (ByValStrStruct* data, char* correctString)
1082 {
1083         int ret;
1084
1085         ret = strcmp(data->a, correctString);
1086         // printf ("T1: %s\n", data->a);
1087         // printf ("T2: %s\n", correctString);
1088
1089         marshal_free (data);
1090         return (ret != 0);
1091 }
1092
1093 typedef struct {
1094         guint16 a[4];
1095         int  flag;
1096 } ByValStrStruct_Unicode;
1097
1098 LIBTEST_API int STDCALL 
1099 mono_test_byvalstr_check_unicode (ByValStrStruct_Unicode *ref, int test)
1100 {
1101         if (ref->flag != 0x1234abcd){
1102                 printf ("overwritten data");
1103                 return 1;
1104         }
1105             
1106         if (test == 1 || test == 3){
1107                 if (ref->a [0] != '1' ||
1108                     ref->a [1] != '2'   ||
1109                     ref->a [2] != '3')
1110                         return 1;
1111                 return 0;
1112         }
1113         if (test == 2){
1114                 if (ref->a [0] != '1' ||
1115                     ref->a [1] != '2')
1116                         return 1;
1117                 return 0;
1118         }
1119         return 10;
1120 }
1121
1122 LIBTEST_API int STDCALL 
1123 NameManglingAnsi (char *data)
1124 {
1125         return data [0] + data [1] + data [2];
1126 }
1127
1128 LIBTEST_API int STDCALL 
1129 NameManglingAnsiA (char *data)
1130 {
1131         g_assert_not_reached ();
1132 }
1133
1134 LIBTEST_API int STDCALL 
1135 NameManglingAnsiW (char *data)
1136 {
1137         g_assert_not_reached ();
1138 }
1139
1140 LIBTEST_API int STDCALL 
1141 NameManglingAnsi2A (char *data)
1142 {
1143         return data [0] + data [1] + data [2];
1144 }
1145
1146 LIBTEST_API int STDCALL 
1147 NameManglingAnsi2W (char *data)
1148 {
1149         g_assert_not_reached ();
1150 }
1151
1152 LIBTEST_API int STDCALL 
1153 NameManglingUnicode (char *data)
1154 {
1155         g_assert_not_reached ();
1156 }
1157
1158 LIBTEST_API int STDCALL 
1159 NameManglingUnicodeW (gunichar2 *data)
1160 {
1161         return data [0] + data [1] + data [2];
1162 }
1163
1164 LIBTEST_API int STDCALL 
1165 NameManglingUnicode2 (gunichar2 *data)
1166 {
1167         return data [0] + data [1] + data [2];
1168 }
1169
1170 LIBTEST_API int STDCALL 
1171 NameManglingAutoW (char *data)
1172 {
1173 #ifdef WIN32
1174         return (data [0] + data [1] + data [2]) == 131 ? 0 : 1;
1175 #else
1176         g_assert_not_reached ();
1177 #endif
1178 }
1179
1180 LIBTEST_API int STDCALL 
1181 NameManglingAuto (char *data)
1182 {
1183 #ifndef WIN32
1184         return (data [0] + data [1] + data [2]) == 198 ? 0 : 1;
1185 #else
1186         g_assert_not_reached ();
1187 #endif
1188 }
1189
1190 typedef int (STDCALL *intcharFunc)(const char*);
1191
1192 LIBTEST_API void STDCALL 
1193 callFunction (intcharFunc f)
1194 {
1195         f ("ABC");
1196 }
1197
1198 typedef struct {
1199         const char* str;
1200         int i;
1201 } SimpleObj;
1202
1203 LIBTEST_API int STDCALL 
1204 class_marshal_test0 (SimpleObj *obj1)
1205 {
1206         // printf ("class_marshal_test0 %s %d\n", obj1->str, obj1->i);
1207
1208         if (strcmp(obj1->str, "T1"))
1209                 return -1;
1210         if (obj1->i != 4)
1211                 return -2;
1212
1213         return 0;
1214 }
1215
1216 LIBTEST_API int STDCALL 
1217 class_marshal_test4 (SimpleObj *obj1)
1218 {
1219         if (obj1)
1220                 return -1;
1221
1222         return 0;
1223 }
1224
1225 LIBTEST_API void STDCALL
1226 class_marshal_test1 (SimpleObj **obj1)
1227 {
1228         SimpleObj *res = malloc (sizeof (SimpleObj));
1229
1230         res->str = g_strdup ("ABC");
1231         res->i = 5;
1232
1233         *obj1 = res;
1234 }
1235
1236 LIBTEST_API int STDCALL 
1237 class_marshal_test2 (SimpleObj **obj1)
1238 {
1239         // printf ("class_marshal_test2 %s %d\n", (*obj1)->str, (*obj1)->i);
1240
1241         if (strcmp((*obj1)->str, "ABC"))
1242                 return -1;
1243         if ((*obj1)->i != 5)
1244                 return -2;
1245
1246         return 0;
1247 }
1248
1249 LIBTEST_API int STDCALL 
1250 string_marshal_test0 (char *str)
1251 {
1252         if (strcmp (str, "TEST0"))
1253                 return -1;
1254
1255         return 0;
1256 }
1257
1258 LIBTEST_API void STDCALL
1259 string_marshal_test1 (const char **str)
1260 {
1261         *str = g_strdup ("TEST1");
1262 }
1263
1264 LIBTEST_API int STDCALL 
1265 string_marshal_test2 (char **str)
1266 {
1267         // printf ("string_marshal_test2 %s\n", *str);
1268
1269         if (strcmp (*str, "TEST1"))
1270                 return -1;
1271
1272         return 0;
1273 }
1274
1275 LIBTEST_API int STDCALL 
1276 string_marshal_test3 (char *str)
1277 {
1278         if (str)
1279                 return -1;
1280
1281         return 0;
1282 }
1283
1284 typedef struct {
1285         int a;
1286         int b;
1287 } BlittableClass;
1288
1289 LIBTEST_API BlittableClass* STDCALL 
1290 TestBlittableClass (BlittableClass *vl)
1291 {
1292         BlittableClass *res;
1293
1294         // printf ("TestBlittableClass %d %d\n", vl->a, vl->b);
1295
1296         if (vl) {
1297                 vl->a++;
1298                 vl->b++;
1299
1300                 res = g_new0 (BlittableClass, 1);
1301                 memcpy (res, vl, sizeof (BlittableClass));
1302         } else {
1303                 res = g_new0 (BlittableClass, 1);
1304                 res->a = 42;
1305                 res->b = 43;
1306         }
1307
1308         return res;
1309 }
1310
1311 typedef struct OSVERSIONINFO_STRUCT
1312
1313         int a; 
1314         int b; 
1315 } OSVERSIONINFO_STRUCT;
1316
1317 LIBTEST_API int STDCALL  
1318 MyGetVersionEx (OSVERSIONINFO_STRUCT *osvi)
1319 {
1320
1321         // printf ("GOT %d %d\n", osvi->a, osvi->b);
1322
1323         osvi->a += 1;
1324         osvi->b += 1;
1325
1326         return osvi->a + osvi->b;
1327 }
1328
1329 LIBTEST_API int STDCALL  
1330 BugGetVersionEx (int a, int b, int c, int d, int e, int f, int g, int h, OSVERSIONINFO_STRUCT *osvi)
1331 {
1332
1333         // printf ("GOT %d %d\n", osvi->a, osvi->b);
1334
1335         osvi->a += 1;
1336         osvi->b += 1;
1337
1338         return osvi->a + osvi->b;
1339 }
1340
1341 LIBTEST_API int STDCALL 
1342 mono_test_marshal_point (point pt)
1343 {
1344         // printf("point %g %g\n", pt.x, pt.y);
1345         if (pt.x == 1.25 && pt.y == 3.5)
1346                 return 0;
1347
1348         return 1;
1349 }
1350
1351 typedef struct {
1352         int x;
1353         double y;
1354 } mixed_point;
1355
1356 LIBTEST_API int STDCALL 
1357 mono_test_marshal_mixed_point (mixed_point pt)
1358 {
1359         // printf("mixed point %d %g\n", pt.x, pt.y);
1360         if (pt.x == 5 && pt.y == 6.75)
1361                 return 0;
1362
1363         return 1;
1364 }
1365
1366 LIBTEST_API int STDCALL 
1367 mono_test_marshal_mixed_point_2 (mixed_point *pt)
1368 {
1369         if (pt->x != 5 || pt->y != 6.75)
1370                 return 1;
1371
1372         pt->x = 10;
1373         pt->y = 12.35;
1374
1375         return 0;
1376 }
1377
1378 LIBTEST_API int STDCALL  
1379 marshal_test_ref_bool(int i, char *b1, short *b2, int *b3)
1380 {
1381     int res = 1;
1382     if (*b1 != 0 && *b1 != 1)
1383         return 1;
1384     if (*b2 != 0 && *b2 != -1) /* variant_bool */
1385         return 1;
1386     if (*b3 != 0 && *b3 != 1)
1387         return 1;
1388     if (i == ((*b1 << 2) | (-*b2 << 1) | *b3))
1389         res = 0;
1390     *b1 = !*b1;
1391     *b2 = ~*b2;
1392     *b3 = !*b3;
1393     return res;
1394 }
1395
1396 struct BoolStruct
1397 {
1398     int i;
1399     char b1;
1400     short b2; /* variant_bool */
1401     int b3;
1402 };
1403
1404 LIBTEST_API int STDCALL  
1405 marshal_test_bool_struct(struct BoolStruct *s)
1406 {
1407     int res = 1;
1408     if (s->b1 != 0 && s->b1 != 1)
1409         return 1;
1410     if (s->b2 != 0 && s->b2 != -1)
1411         return 1;
1412     if (s->b3 != 0 && s->b3 != 1)
1413         return 1;
1414     if (s->i == ((s->b1 << 2) | (-s->b2 << 1) | s->b3))
1415         res = 0;
1416     s->b1 = !s->b1;
1417     s->b2 = ~s->b2;
1418     s->b3 = !s->b3;
1419     return res;
1420 }
1421
1422 typedef struct {
1423         gint64 l;
1424 } LongStruct2;
1425
1426 typedef struct {
1427         int i;
1428         LongStruct2 l;
1429 } LongStruct;
1430
1431 LIBTEST_API int STDCALL
1432 mono_test_marshal_long_struct (LongStruct *s)
1433 {
1434         return s->i + s->l.l;
1435 }
1436
1437 LIBTEST_API void STDCALL
1438 mono_test_last_error (int err)
1439 {
1440 #ifdef WIN32
1441         SetLastError (err);
1442 #else
1443         errno = err;
1444 #endif
1445 }
1446
1447 LIBTEST_API int STDCALL 
1448 mono_test_asany (void *ptr, int what)
1449 {
1450         switch (what) {
1451         case 1:
1452                 return (*(int*)ptr == 5) ? 0 : 1;
1453         case 2:
1454                 return strcmp (ptr, "ABC") == 0 ? 0 : 1;
1455         case 3: {
1456                 simplestruct2 ss = *(simplestruct2*)ptr;
1457
1458                 if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
1459             !strcmp (ss.d, "TEST") && 
1460             ss.e == 99 && ss.f == 1.5 && ss.g == 42 && ss.h == (guint64)123)
1461                         return 0;
1462                 else
1463                         return 1;
1464         }
1465         case 4: {
1466                 GError *error = NULL;
1467                 char *s;
1468
1469                 s = g_utf16_to_utf8 (ptr, -1, NULL, NULL, &error);
1470                 if (!strcmp (s, "ABC")) {
1471                         g_free (s);
1472                         return 0;
1473                 }
1474                 else {
1475                         g_free (s);
1476                         return 1;
1477                 }
1478         }
1479         default:
1480                 g_assert_not_reached ();
1481         }
1482
1483         return 1;
1484 }
1485
1486 typedef struct
1487 {
1488         int i;
1489         int j;
1490         int k;
1491         char *s;
1492 } AsAnyStruct;
1493
1494 LIBTEST_API int STDCALL 
1495 mono_test_marshal_asany_in (void* ptr)
1496 {
1497         AsAnyStruct* asAny = ptr;
1498         int res = asAny->i + asAny->j + asAny->k;
1499
1500         return res;
1501 }
1502
1503 LIBTEST_API int STDCALL 
1504 mono_test_marshal_asany_inout (void* ptr)
1505 {
1506         AsAnyStruct* asAny = ptr;
1507         int res = asAny->i + asAny->j + asAny->k;
1508
1509         marshal_free (asAny->s);
1510
1511         asAny->i = 10;
1512         asAny->j = 20;
1513         asAny->k = 30;
1514         asAny->s = 0;
1515
1516         return res;
1517 }
1518
1519 LIBTEST_API int STDCALL 
1520 mono_test_marshal_asany_out (void* ptr)
1521 {
1522         AsAnyStruct* asAny = ptr;
1523         int res = asAny->i + asAny->j + asAny->k;
1524
1525         asAny->i = 10;
1526         asAny->j = 20;
1527         asAny->k = 30;
1528         asAny->s = 0;
1529
1530         return res;
1531 }
1532
1533 /*
1534  * AMD64 marshalling tests.
1535  */
1536
1537 typedef struct amd64_struct1 {
1538         int i;
1539         int j;
1540         int k;
1541         int l;
1542 } amd64_struct1;
1543
1544 LIBTEST_API amd64_struct1 STDCALL 
1545 mono_test_marshal_amd64_pass_return_struct1 (amd64_struct1 s)
1546 {
1547         s.i ++;
1548         s.j ++;
1549         s.k ++;
1550         s.l ++;
1551
1552         return s;
1553 }
1554
1555 LIBTEST_API amd64_struct1 STDCALL 
1556 mono_test_marshal_amd64_pass_return_struct1_many_args (amd64_struct1 s, int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8)
1557 {
1558         s.i ++;
1559         s.j ++;
1560         s.k ++;
1561         s.l += 1 + i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8;
1562
1563         return s;
1564 }
1565
1566 typedef struct amd64_struct2 {
1567         int i;
1568         int j;
1569 } amd64_struct2;
1570
1571 LIBTEST_API amd64_struct2 STDCALL 
1572 mono_test_marshal_amd64_pass_return_struct2 (amd64_struct2 s)
1573 {
1574         s.i ++;
1575         s.j ++;
1576
1577         return s;
1578 }
1579
1580 typedef struct amd64_struct3 {
1581         int i;
1582 } amd64_struct3;
1583
1584 LIBTEST_API amd64_struct3 STDCALL 
1585 mono_test_marshal_amd64_pass_return_struct3 (amd64_struct3 s)
1586 {
1587         s.i ++;
1588
1589         return s;
1590 }
1591
1592 typedef struct amd64_struct4 {
1593         double d1, d2;
1594 } amd64_struct4;
1595
1596 LIBTEST_API amd64_struct4 STDCALL 
1597 mono_test_marshal_amd64_pass_return_struct4 (amd64_struct4 s)
1598 {
1599         s.d1 ++;
1600         s.d2 ++;
1601
1602         return s;
1603 }
1604
1605 /*
1606  * IA64 marshalling tests.
1607  */
1608 typedef struct test_struct5 {
1609         float d1, d2;
1610 } test_struct5;
1611
1612 LIBTEST_API test_struct5 STDCALL 
1613 mono_test_marshal_ia64_pass_return_struct5 (double d1, double d2, test_struct5 s, int i, double d3, double d4)
1614 {
1615         s.d1 += d1 + d2 + i;
1616         s.d2 += d3 + d4 + i;
1617
1618         return s;
1619 }
1620
1621 typedef struct test_struct6 {
1622         double d1, d2;
1623 } test_struct6;
1624
1625 LIBTEST_API test_struct6 STDCALL 
1626 mono_test_marshal_ia64_pass_return_struct6 (double d1, double d2, test_struct6 s, int i, double d3, double d4)
1627 {
1628         s.d1 += d1 + d2 + i;
1629         s.d2 += d3 + d4;
1630
1631         return s;
1632 }
1633
1634 static guint32 custom_res [2];
1635
1636 LIBTEST_API void* STDCALL
1637 mono_test_marshal_pass_return_custom (int i, guint32 *ptr, int j)
1638 {
1639         /* ptr will be freed by CleanupNative, so make a copy */
1640         custom_res [0] = 0; /* not allocated by AllocHGlobal */
1641         custom_res [1] = ptr [1];
1642
1643         return &custom_res;
1644 }
1645
1646 LIBTEST_API int STDCALL 
1647 mono_test_marshal_pass_out_custom (int i, guint32 **ptr, int j)
1648 {
1649         custom_res [0] = 0;
1650         custom_res [1] = i + j + 10;
1651
1652         *ptr = custom_res;
1653
1654         return 0;
1655 }
1656
1657 LIBTEST_API int STDCALL 
1658 mono_test_marshal_pass_inout_custom (int i, guint32 *ptr, int j)
1659 {
1660         ptr [0] = 0;
1661         ptr [1] = i + ptr [1] + j;
1662
1663         return 0;
1664 }
1665
1666 LIBTEST_API int STDCALL 
1667 mono_test_marshal_pass_out_byval_custom (int i, guint32 *ptr, int j)
1668 {
1669         return ptr == NULL ? 0 : 1;
1670 }
1671
1672 LIBTEST_API int STDCALL 
1673 mono_test_marshal_pass_byref_custom (int i, guint32 **ptr, int j)
1674 {
1675         (*ptr)[1] += i + j;
1676
1677         return 0;
1678 }
1679
1680 LIBTEST_API void* STDCALL
1681 mono_test_marshal_pass_return_custom2 (int i, guint32 *ptr, int j)
1682 {
1683         g_assert_not_reached ();
1684
1685         return NULL;
1686 }
1687
1688 LIBTEST_API void* STDCALL
1689 mono_test_marshal_pass_return_custom_null (int i, guint32 *ptr, int j)
1690 {
1691         g_assert (ptr == NULL);
1692
1693         return NULL;
1694 }
1695
1696 typedef void *(STDCALL *PassReturnPtrDelegate) (void *ptr);
1697
1698 LIBTEST_API int STDCALL 
1699 mono_test_marshal_pass_return_custom_in_delegate (PassReturnPtrDelegate del)
1700 {
1701         guint32 buf [2];
1702         guint32 res;
1703         guint32 *ptr;
1704
1705         buf [0] = 0;
1706         buf [1] = 10;
1707
1708         ptr = del (&buf);
1709
1710         res = ptr [1];
1711
1712 #ifdef WIN32
1713         /* FIXME: Freed with FreeHGlobal */
1714 #else
1715         g_free (ptr);
1716 #endif
1717
1718         return res;
1719 }
1720
1721 LIBTEST_API int STDCALL 
1722 mono_test_marshal_pass_return_custom_null_in_delegate (PassReturnPtrDelegate del)
1723 {
1724         void *ptr = del (NULL);
1725
1726         return (ptr == NULL) ? 15 : 0;
1727 }
1728
1729 typedef void (STDCALL *CustomOutParamDelegate) (void **pptr);
1730
1731 LIBTEST_API int STDCALL 
1732 mono_test_marshal_custom_out_param_delegate (CustomOutParamDelegate del)
1733 {
1734         void* pptr = del;
1735
1736         del (&pptr);
1737
1738         if(pptr != NULL)
1739                 return 1;
1740
1741         return 0;
1742 }
1743
1744 typedef int (STDCALL *ReturnEnumDelegate) (int e);
1745
1746 LIBTEST_API int STDCALL 
1747 mono_test_marshal_return_enum_delegate (ReturnEnumDelegate func)
1748 {
1749         return func (1);
1750 }
1751
1752 typedef struct {
1753         int a, b, c;
1754         gint64 d;
1755 } BlittableStruct;
1756         
1757 typedef BlittableStruct (STDCALL *SimpleDelegate10) (BlittableStruct ss);
1758
1759 LIBTEST_API int STDCALL 
1760 mono_test_marshal_blittable_struct_delegate (SimpleDelegate10 delegate)
1761 {
1762         BlittableStruct ss, res;
1763
1764         ss.a = 1;
1765         ss.b = 2;
1766         ss.c = 3;
1767         ss.d = 55;
1768
1769         res = delegate (ss);
1770         if (! ((res.a == -1) && (res.b == -2) && (res.c == -3) && (res.d == -55)))
1771                 return 1;
1772
1773         return 0;
1774 }
1775
1776 LIBTEST_API int STDCALL 
1777 mono_test_stdcall_name_mangling (int a, int b, int c)
1778 {
1779         return a + b + c;
1780 }
1781
1782 /*
1783  * PASSING AND RETURNING SMALL STRUCTURES FROM DELEGATES TESTS
1784  */
1785
1786 typedef struct {
1787         int i;
1788 } SmallStruct1;
1789         
1790 typedef SmallStruct1 (STDCALL *SmallStructDelegate1) (SmallStruct1 ss);
1791
1792 LIBTEST_API int STDCALL 
1793 mono_test_marshal_small_struct_delegate1 (SmallStructDelegate1 delegate)
1794 {
1795         SmallStruct1 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         gint16 i, j;
1808 } SmallStruct2;
1809         
1810 typedef SmallStruct2 (STDCALL *SmallStructDelegate2) (SmallStruct2 ss);
1811
1812 LIBTEST_API int STDCALL 
1813 mono_test_marshal_small_struct_delegate2 (SmallStructDelegate2 delegate)
1814 {
1815         SmallStruct2 ss, res;
1816
1817         ss.i = 2;
1818         ss.j = 3;
1819
1820         res = delegate (ss);
1821         if (! ((res.i == -2) && (res.j == -3)))
1822                 return 1;
1823
1824         return 0;
1825 }
1826
1827 typedef struct {
1828         gint16 i;
1829         gint8 j;
1830 } SmallStruct3;
1831         
1832 typedef SmallStruct3 (STDCALL *SmallStructDelegate3) (SmallStruct3 ss);
1833
1834 LIBTEST_API int STDCALL 
1835 mono_test_marshal_small_struct_delegate3 (SmallStructDelegate3 delegate)
1836 {
1837         SmallStruct3 ss, res;
1838
1839         ss.i = 1;
1840         ss.j = 2;
1841
1842         res = delegate (ss);
1843         if (! ((res.i == -1) && (res.j == -2)))
1844                 return 1;
1845
1846         return 0;
1847 }
1848
1849 typedef struct {
1850         gint16 i;
1851 } SmallStruct4;
1852         
1853 typedef SmallStruct4 (STDCALL *SmallStructDelegate4) (SmallStruct4 ss);
1854
1855 LIBTEST_API int STDCALL 
1856 mono_test_marshal_small_struct_delegate4 (SmallStructDelegate4 delegate)
1857 {
1858         SmallStruct4 ss, res;
1859
1860         ss.i = 1;
1861
1862         res = delegate (ss);
1863         if (! (res.i == -1))
1864                 return 1;
1865
1866         return 0;
1867 }
1868
1869 typedef struct {
1870         gint64 i;
1871 } SmallStruct5;
1872         
1873 typedef SmallStruct5 (STDCALL *SmallStructDelegate5) (SmallStruct5 ss);
1874
1875 LIBTEST_API int STDCALL 
1876 mono_test_marshal_small_struct_delegate5 (SmallStructDelegate5 delegate)
1877 {
1878         SmallStruct5 ss, res;
1879
1880         ss.i = 5;
1881
1882         res = delegate (ss);
1883         if (! (res.i == -5))
1884                 return 1;
1885
1886         return 0;
1887 }
1888
1889 typedef struct {
1890         int i, j;
1891 } SmallStruct6;
1892         
1893 typedef SmallStruct6 (STDCALL *SmallStructDelegate6) (SmallStruct6 ss);
1894
1895 LIBTEST_API int STDCALL 
1896 mono_test_marshal_small_struct_delegate6 (SmallStructDelegate6 delegate)
1897 {
1898         SmallStruct6 ss, res;
1899
1900         ss.i = 1;
1901         ss.j = 2;
1902
1903         res = delegate (ss);
1904         if (! ((res.i == -1) && (res.j == -2)))
1905                 return 1;
1906
1907         return 0;
1908 }
1909
1910 typedef struct {
1911         int i;
1912         gint16 j;
1913 } SmallStruct7;
1914         
1915 typedef SmallStruct7 (STDCALL *SmallStructDelegate7) (SmallStruct7 ss);
1916
1917 LIBTEST_API int STDCALL 
1918 mono_test_marshal_small_struct_delegate7 (SmallStructDelegate7 delegate)
1919 {
1920         SmallStruct7 ss, res;
1921
1922         ss.i = 1;
1923         ss.j = 2;
1924
1925         res = delegate (ss);
1926         if (! ((res.i == -1) && (res.j == -2)))
1927                 return 1;
1928
1929         return 0;
1930 }
1931
1932 typedef struct {
1933         float i;
1934 } SmallStruct8;
1935         
1936 typedef SmallStruct8 (STDCALL *SmallStructDelegate8) (SmallStruct8 ss);
1937
1938 LIBTEST_API int STDCALL 
1939 mono_test_marshal_small_struct_delegate8 (SmallStructDelegate8 delegate)
1940 {
1941         SmallStruct8 ss, res;
1942
1943         ss.i = 1.0;
1944
1945         res = delegate (ss);
1946         if (! ((res.i == -1.0)))
1947                 return 1;
1948
1949         return 0;
1950 }
1951
1952 typedef struct {
1953         double i;
1954 } SmallStruct9;
1955         
1956 typedef SmallStruct9 (STDCALL *SmallStructDelegate9) (SmallStruct9 ss);
1957
1958 LIBTEST_API int STDCALL 
1959 mono_test_marshal_small_struct_delegate9 (SmallStructDelegate9 delegate)
1960 {
1961         SmallStruct9 ss, res;
1962
1963         ss.i = 1.0;
1964
1965         res = delegate (ss);
1966         if (! ((res.i == -1.0)))
1967                 return 1;
1968
1969         return 0;
1970 }
1971
1972 typedef struct {
1973         float i, j;
1974 } SmallStruct10;
1975         
1976 typedef SmallStruct10 (STDCALL *SmallStructDelegate10) (SmallStruct10 ss);
1977
1978 LIBTEST_API int STDCALL 
1979 mono_test_marshal_small_struct_delegate10 (SmallStructDelegate10 delegate)
1980 {
1981         SmallStruct10 ss, res;
1982
1983         ss.i = 1.0;
1984         ss.j = 2.0;
1985
1986         res = delegate (ss);
1987         if (! ((res.i == -1.0) && (res.j == -2.0)))
1988                 return 1;
1989
1990         return 0;
1991 }
1992
1993 typedef struct {
1994         float i;
1995         int j;
1996 } SmallStruct11;
1997         
1998 typedef SmallStruct11 (STDCALL *SmallStructDelegate11) (SmallStruct11 ss);
1999
2000 LIBTEST_API int STDCALL 
2001 mono_test_marshal_small_struct_delegate11 (SmallStructDelegate11 delegate)
2002 {
2003         SmallStruct11 ss, res;
2004
2005         ss.i = 1.0;
2006         ss.j = 2;
2007
2008         res = delegate (ss);
2009         if (! ((res.i == -1.0) && (res.j == -2)))
2010                 return 1;
2011
2012         return 0;
2013 }
2014
2015 typedef int (STDCALL *ArrayDelegate) (int i, char *j, void *arr);
2016
2017 LIBTEST_API int STDCALL 
2018 mono_test_marshal_array_delegate (void *arr, int len, ArrayDelegate del)
2019 {
2020         return del (len, NULL, arr);
2021 }
2022
2023 LIBTEST_API int STDCALL 
2024 mono_test_marshal_out_array_delegate (int *arr, int len, ArrayDelegate del)
2025 {
2026         del (len, NULL, arr);
2027
2028         if ((arr [0] != 1) || (arr [1] != 2))
2029                 return 1;
2030         else
2031                 return 0;
2032 }
2033
2034 typedef gunichar2* (STDCALL *UnicodeStringDelegate) (gunichar2 *message);
2035
2036 LIBTEST_API int STDCALL 
2037 mono_test_marshal_return_unicode_string_delegate (UnicodeStringDelegate del)
2038 {
2039         const char m[] = "abcdef";
2040         gunichar2 *s2, *res;
2041         glong len;
2042
2043         s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
2044
2045         res = del (s2);
2046
2047         marshal_free (res);
2048
2049         return 0;
2050 }
2051
2052 LIBTEST_API int STDCALL 
2053 mono_test_marshal_out_string_array_delegate (char **arr, int len, ArrayDelegate del)
2054 {
2055         del (len, NULL, arr);
2056
2057         if (!strcmp (arr [0], "ABC") && !strcmp (arr [1], "DEF"))
2058                 return 0;
2059         else
2060                 return 1;
2061 }
2062
2063 typedef int (*CdeclDelegate) (int i, int j);
2064
2065 LIBTEST_API int STDCALL 
2066 mono_test_marshal_cdecl_delegate (CdeclDelegate del)
2067 {
2068         int i;
2069
2070         for (i = 0; i < 1000; ++i)
2071                 del (1, 2);
2072
2073         return 0;
2074 }
2075
2076 typedef char** (STDCALL *ReturnStringArrayDelegate) (int i);
2077
2078 LIBTEST_API int STDCALL 
2079 mono_test_marshal_return_string_array_delegate (ReturnStringArrayDelegate d)
2080 {
2081         char **arr = d (2);
2082         int res;
2083
2084         if (arr == NULL)
2085                 return 3;
2086
2087         if (strcmp (arr [0], "ABC") || strcmp (arr [1], "DEF"))
2088                 res = 1;
2089         else
2090                 res = 0;
2091
2092         marshal_free (arr);
2093
2094         return res;
2095 }
2096
2097 typedef int (STDCALL *ByrefStringDelegate) (char **s);
2098
2099 LIBTEST_API int STDCALL 
2100 mono_test_marshal_byref_string_delegate (ByrefStringDelegate d)
2101 {
2102         char *s = (char*)"ABC";
2103         int res;
2104
2105         res = d (&s);
2106         if (res != 0)
2107                 return res;
2108
2109         if (!strcmp (s, "DEF"))
2110                 res = 0;
2111         else
2112                 res = 2;
2113
2114         marshal_free (s);
2115
2116         return res;
2117 }
2118
2119 LIBTEST_API int STDCALL 
2120 add_delegate (int i, int j)
2121 {
2122         return i + j;
2123 }
2124
2125 LIBTEST_API gpointer STDCALL 
2126 mono_test_marshal_return_fnptr (void)
2127 {
2128         return &add_delegate;
2129 }
2130
2131 LIBTEST_API int STDCALL 
2132 mono_xr (int code)
2133 {
2134         printf ("codigo %x\n", code);
2135         return code + 1234;
2136 }
2137
2138 typedef struct {
2139         int handle;
2140 } HandleRef;
2141
2142 LIBTEST_API HandleRef STDCALL 
2143 mono_xr_as_handle (int code)
2144 {
2145         HandleRef ref;
2146
2147         memset (&ref, 0, sizeof (ref));
2148
2149         return ref;
2150 }
2151  
2152 typedef struct {
2153         int   a;
2154         void *handle1;
2155         void *handle2;
2156         int   b;
2157 } HandleStructs;
2158
2159 LIBTEST_API int STDCALL 
2160 mono_safe_handle_struct_ref (HandleStructs *x)
2161 {
2162         printf ("Dingus Ref! \n");
2163         printf ("Values: %d %d %p %p\n", x->a, x->b, x->handle1, x->handle2);
2164         if (x->a != 1234)
2165                 return 1;
2166         if (x->b != 8743)
2167                 return 2;
2168
2169         if (x->handle1 != (void*) 0x7080feed)
2170                 return 3;
2171
2172         if (x->handle2 != (void*) 0x1234abcd)
2173                 return 4;
2174
2175         return 0xf00d;
2176 }
2177
2178 LIBTEST_API int STDCALL 
2179 mono_safe_handle_struct (HandleStructs x)
2180 {
2181         printf ("Dingus Standard! \n");
2182         printf ("Values: %d %d %p %p\n", x.a, x.b, x.handle1, x.handle2);
2183         if (x.a != 1234)
2184                 return 1;
2185         if (x.b != 8743)
2186                 return 2;
2187
2188         if (x.handle1 != (void*) 0x7080feed)
2189                 return 3;
2190
2191         if (x.handle2 != (void*) 0x1234abcd)
2192                 return 4;
2193         
2194         return 0xf00f;
2195 }
2196
2197 typedef struct {
2198         void *a;
2199 } TrivialHandle;
2200
2201 LIBTEST_API int STDCALL 
2202 mono_safe_handle_struct_simple (TrivialHandle x)
2203 {
2204         printf ("The value is %p\n", x.a);
2205         return ((int)(gsize)x.a) * 2;
2206 }
2207
2208 LIBTEST_API int STDCALL 
2209 mono_safe_handle_return (void)
2210 {
2211         return 0x1000f00d;
2212 }
2213
2214 LIBTEST_API void STDCALL
2215 mono_safe_handle_ref (void **handle)
2216 {
2217         if (*handle != 0){
2218                 *handle = (void *) 0xbad;
2219                 return;
2220         }
2221
2222         *handle = (void *) 0x800d;
2223 }
2224 /*
2225  * COM INTEROP TESTS
2226  */
2227
2228 #ifdef WIN32
2229
2230 LIBTEST_API int STDCALL 
2231 mono_test_marshal_bstr_in(BSTR bstr)
2232 {
2233         if (!wcscmp(bstr, L"mono_test_marshal_bstr_in"))
2234                 return 0;
2235         return 1;
2236 }
2237
2238 LIBTEST_API int STDCALL 
2239 mono_test_marshal_bstr_out(BSTR* bstr)
2240 {
2241         *bstr = SysAllocString(L"mono_test_marshal_bstr_out");
2242         return 0;
2243 }
2244
2245 LIBTEST_API int STDCALL 
2246 mono_test_marshal_bstr_in_null(BSTR bstr)
2247 {
2248         if (!bstr)
2249                 return 0;
2250         return 1;
2251 }
2252
2253 LIBTEST_API int STDCALL 
2254 mono_test_marshal_bstr_out_null(BSTR* bstr)
2255 {
2256         *bstr = NULL;
2257         return 0;
2258 }
2259
2260 LIBTEST_API int STDCALL 
2261 mono_test_marshal_variant_in_sbyte(VARIANT variant)
2262 {
2263         if (variant.vt == VT_I1 && variant.cVal == 100)
2264                 return 0;
2265         return 1;
2266 }
2267
2268 LIBTEST_API int STDCALL 
2269 mono_test_marshal_variant_in_byte(VARIANT variant)
2270 {
2271         if (variant.vt == VT_UI1 && variant.bVal == 100)
2272                 return 0;
2273         return 1;
2274 }
2275
2276 LIBTEST_API int STDCALL 
2277 mono_test_marshal_variant_in_short(VARIANT variant)
2278 {
2279         if (variant.vt == VT_I2 && variant.iVal == 314)
2280                 return 0;
2281         return 1;
2282 }
2283
2284 LIBTEST_API int STDCALL 
2285 mono_test_marshal_variant_in_ushort(VARIANT variant)
2286 {
2287         if (variant.vt == VT_UI2 && variant.uiVal == 314)
2288                 return 0;
2289         return 1;
2290 }
2291
2292 LIBTEST_API int STDCALL 
2293 mono_test_marshal_variant_in_int(VARIANT variant)
2294 {
2295         if (variant.vt == VT_I4 && variant.lVal == 314)
2296                 return 0;
2297         return 1;
2298 }
2299
2300 LIBTEST_API int STDCALL 
2301 mono_test_marshal_variant_in_uint(VARIANT variant)
2302 {
2303         if (variant.vt == VT_UI4 && variant.ulVal == 314)
2304                 return 0;
2305         return 1;
2306 }
2307
2308 LIBTEST_API int STDCALL 
2309 mono_test_marshal_variant_in_long(VARIANT variant)
2310 {
2311         if (variant.vt == VT_I8 && variant.llVal == 314)
2312                 return 0;
2313         return 1;
2314 }
2315
2316 LIBTEST_API int STDCALL 
2317 mono_test_marshal_variant_in_ulong(VARIANT variant)
2318 {
2319         if (variant.vt == VT_UI8 && variant.ullVal == 314)
2320                 return 0;
2321         return 1;
2322 }
2323
2324 LIBTEST_API int STDCALL 
2325 mono_test_marshal_variant_in_float(VARIANT variant)
2326 {
2327         if (variant.vt == VT_R4 && (variant.fltVal - 3.14)/3.14 < .001)
2328                 return 0;
2329         return 1;
2330 }
2331
2332 LIBTEST_API int STDCALL 
2333 mono_test_marshal_variant_in_double(VARIANT variant)
2334 {
2335         if (variant.vt == VT_R8 && (variant.dblVal - 3.14)/3.14 < .001)
2336                 return 0;
2337         return 1;
2338 }
2339
2340 LIBTEST_API int STDCALL 
2341 mono_test_marshal_variant_in_bstr(VARIANT variant)
2342 {
2343         if (variant.vt == VT_BSTR && !wcscmp(variant.bstrVal, L"PI"))
2344                 return 0;
2345         return 1;
2346 }
2347
2348 LIBTEST_API int STDCALL 
2349 mono_test_marshal_variant_in_bool_true (VARIANT variant)
2350 {
2351         if (variant.vt == VT_BOOL && variant.boolVal == VARIANT_TRUE)
2352                 return 0;
2353         return 1;
2354 }
2355
2356 LIBTEST_API int STDCALL 
2357 mono_test_marshal_variant_in_bool_false (VARIANT variant)
2358 {
2359         if (variant.vt == VT_BOOL && variant.boolVal == VARIANT_FALSE)
2360                 return 0;
2361         return 1;
2362 }
2363
2364 LIBTEST_API int STDCALL 
2365 mono_test_marshal_variant_out_sbyte(VARIANT* variant)
2366 {
2367         variant->vt = VT_I1;
2368         variant->cVal = 100;
2369
2370         return 0;
2371 }
2372
2373 LIBTEST_API int STDCALL 
2374 mono_test_marshal_variant_out_byte(VARIANT* variant)
2375 {       
2376         variant->vt = VT_UI1;
2377         variant->bVal = 100;
2378
2379         return 0;
2380 }
2381
2382 LIBTEST_API int STDCALL 
2383 mono_test_marshal_variant_out_short(VARIANT* variant)
2384 {
2385         variant->vt = VT_I2;
2386         variant->iVal = 314;
2387
2388         return 0;
2389 }
2390
2391 LIBTEST_API int STDCALL 
2392 mono_test_marshal_variant_out_ushort(VARIANT* variant)
2393 {
2394         variant->vt = VT_UI2;
2395         variant->uiVal = 314;
2396
2397         return 0;
2398 }
2399
2400 LIBTEST_API int STDCALL 
2401 mono_test_marshal_variant_out_int(VARIANT* variant)
2402 {
2403         variant->vt = VT_I4;
2404         variant->lVal = 314;
2405
2406         return 0;
2407 }
2408
2409 LIBTEST_API int STDCALL 
2410 mono_test_marshal_variant_out_uint(VARIANT* variant)
2411 {
2412         variant->vt = VT_UI4;
2413         variant->ulVal = 314;
2414
2415         return 0;
2416 }
2417
2418 LIBTEST_API int STDCALL 
2419 mono_test_marshal_variant_out_long(VARIANT* variant)
2420 {
2421         variant->vt = VT_I8;
2422         variant->llVal = 314;
2423
2424         return 0;
2425 }
2426
2427 LIBTEST_API int STDCALL 
2428 mono_test_marshal_variant_out_ulong(VARIANT* variant)
2429 {
2430         variant->vt = VT_UI8;
2431         variant->ullVal = 314;
2432
2433         return 0;
2434 }
2435
2436 LIBTEST_API int STDCALL 
2437 mono_test_marshal_variant_out_float(VARIANT* variant)
2438 {
2439         variant->vt = VT_R4;
2440         variant->fltVal = 3.14;
2441
2442         return 0;
2443 }
2444
2445 LIBTEST_API int STDCALL 
2446 mono_test_marshal_variant_out_double(VARIANT* variant)
2447 {
2448         variant->vt = VT_R8;
2449         variant->dblVal = 3.14;
2450
2451         return 0;
2452 }
2453
2454 LIBTEST_API int STDCALL 
2455 mono_test_marshal_variant_out_bstr(VARIANT* variant)
2456 {
2457         variant->vt = VT_BSTR;
2458         variant->bstrVal = SysAllocString(L"PI");
2459
2460         return 0;
2461 }
2462
2463 LIBTEST_API int STDCALL 
2464 mono_test_marshal_variant_out_bool_true (VARIANT* variant)
2465 {
2466         variant->vt = VT_BOOL;
2467         variant->boolVal = VARIANT_TRUE;
2468
2469         return 0;
2470 }
2471
2472 LIBTEST_API int STDCALL 
2473 mono_test_marshal_variant_out_bool_false (VARIANT* variant)
2474 {
2475         variant->vt = VT_BOOL;
2476         variant->boolVal = VARIANT_FALSE;
2477
2478         return 0;
2479 }
2480
2481 typedef int (STDCALL *VarFunc) (int vt, VARIANT variant);
2482 typedef int (STDCALL *VarRefFunc) (int vt, VARIANT* variant);
2483
2484 LIBTEST_API int STDCALL 
2485 mono_test_marshal_variant_in_sbyte_unmanaged(VarFunc func)
2486 {
2487         VARIANT vt;
2488         vt.vt = VT_I1;
2489         vt.cVal = -100;
2490         return func (VT_I1, vt);
2491 }
2492
2493 LIBTEST_API int STDCALL 
2494 mono_test_marshal_variant_in_byte_unmanaged(VarFunc func)
2495 {
2496         VARIANT vt;
2497         vt.vt = VT_UI1;
2498         vt.bVal = 100;
2499         return func (VT_UI1, vt);
2500 }
2501
2502 LIBTEST_API int STDCALL 
2503 mono_test_marshal_variant_in_short_unmanaged(VarFunc func)
2504 {
2505         VARIANT vt;
2506         vt.vt = VT_I2;
2507         vt.iVal = -100;
2508         return func (VT_I2, vt);
2509 }
2510
2511 LIBTEST_API int STDCALL 
2512 mono_test_marshal_variant_in_ushort_unmanaged(VarFunc func)
2513 {
2514         VARIANT vt;
2515         vt.vt = VT_UI2;
2516         vt.uiVal = 100;
2517         return func (VT_UI2, vt);
2518 }
2519
2520 LIBTEST_API int STDCALL 
2521 mono_test_marshal_variant_in_int_unmanaged(VarFunc func)
2522 {
2523         VARIANT vt;
2524         vt.vt = VT_I4;
2525         vt.lVal = -100;
2526         return func (VT_I4, vt);
2527 }
2528
2529 LIBTEST_API int STDCALL 
2530 mono_test_marshal_variant_in_uint_unmanaged(VarFunc func)
2531 {
2532         VARIANT vt;
2533         vt.vt = VT_UI4;
2534         vt.ulVal = 100;
2535         return func (VT_UI4, vt);
2536 }
2537
2538 LIBTEST_API int STDCALL 
2539 mono_test_marshal_variant_in_long_unmanaged(VarFunc func)
2540 {
2541         VARIANT vt;
2542         vt.vt = VT_I8;
2543         vt.llVal = -100;
2544         return func (VT_I8, vt);
2545 }
2546
2547 LIBTEST_API int STDCALL 
2548 mono_test_marshal_variant_in_ulong_unmanaged(VarFunc func)
2549 {
2550         VARIANT vt;
2551         vt.vt = VT_UI8;
2552         vt.ullVal = 100;
2553         return func (VT_UI8, vt);
2554 }
2555
2556 LIBTEST_API int STDCALL 
2557 mono_test_marshal_variant_in_float_unmanaged(VarFunc func)
2558 {
2559         VARIANT vt;
2560         vt.vt = VT_R4;
2561         vt.fltVal = 3.14;
2562         return func (VT_R4, vt);
2563 }
2564
2565 LIBTEST_API int STDCALL 
2566 mono_test_marshal_variant_in_double_unmanaged(VarFunc func)
2567 {
2568         VARIANT vt;
2569         vt.vt = VT_R8;
2570         vt.dblVal = 3.14;
2571         return func (VT_R8, vt);
2572 }
2573
2574 LIBTEST_API int STDCALL 
2575 mono_test_marshal_variant_in_bstr_unmanaged(VarFunc func)
2576 {
2577         VARIANT vt;
2578         vt.vt = VT_BSTR;
2579         vt.bstrVal = SysAllocString(L"PI");
2580         return func (VT_BSTR, vt);
2581 }
2582
2583 LIBTEST_API int STDCALL 
2584 mono_test_marshal_variant_in_bool_true_unmanaged(VarFunc func)
2585 {
2586         VARIANT vt;
2587         vt.vt = VT_BOOL;
2588         vt.boolVal = VARIANT_TRUE;
2589         return func (VT_BOOL, vt);
2590 }
2591
2592 LIBTEST_API int STDCALL 
2593 mono_test_marshal_variant_in_bool_false_unmanaged(VarFunc func)
2594 {
2595         VARIANT vt;
2596         vt.vt = VT_BOOL;
2597         vt.boolVal = VARIANT_FALSE;
2598         return func (VT_BOOL, vt);
2599 }
2600
2601 LIBTEST_API int STDCALL 
2602 mono_test_marshal_variant_out_sbyte_unmanaged(VarRefFunc func)
2603 {
2604         VARIANT vt;
2605         VariantInit (&vt);
2606         func (VT_I1, &vt);
2607         if (vt.vt == VT_I1 && vt.cVal == -100)
2608                 return 0;
2609         return 1;
2610 }
2611
2612 LIBTEST_API int STDCALL 
2613 mono_test_marshal_variant_out_byte_unmanaged(VarRefFunc func)
2614 {
2615         VARIANT vt;
2616         VariantInit (&vt);
2617         func (VT_UI1, &vt);
2618         if (vt.vt == VT_UI1 && vt.bVal == 100)
2619                 return 0;
2620         return 1;
2621 }
2622
2623 LIBTEST_API int STDCALL 
2624 mono_test_marshal_variant_out_short_unmanaged(VarRefFunc func)
2625 {
2626         VARIANT vt;
2627         VariantInit (&vt);
2628         func (VT_I2, &vt);
2629         if (vt.vt == VT_I2 && vt.iVal == -100)
2630                 return 0;
2631         return 1;
2632 }
2633
2634 LIBTEST_API int STDCALL 
2635 mono_test_marshal_variant_out_ushort_unmanaged(VarRefFunc func)
2636 {
2637         VARIANT vt;
2638         VariantInit (&vt);
2639         func (VT_UI2, &vt);
2640         if (vt.vt == VT_UI2 && vt.uiVal == 100)
2641                 return 0;
2642         return 1;
2643 }
2644
2645 LIBTEST_API int STDCALL 
2646 mono_test_marshal_variant_out_int_unmanaged(VarRefFunc func)
2647 {
2648         VARIANT vt;
2649         VariantInit (&vt);
2650         func (VT_I4, &vt);
2651         if (vt.vt == VT_I4 && vt.lVal == -100)
2652                 return 0;
2653         return 1;
2654 }
2655
2656 LIBTEST_API int STDCALL 
2657 mono_test_marshal_variant_out_uint_unmanaged(VarRefFunc func)
2658 {
2659         VARIANT vt;
2660         VariantInit (&vt);
2661         func (VT_UI4, &vt);
2662         if (vt.vt == VT_UI4 && vt.ulVal == 100)
2663                 return 0;
2664         return 1;
2665 }
2666
2667 LIBTEST_API int STDCALL 
2668 mono_test_marshal_variant_out_long_unmanaged(VarRefFunc func)
2669 {
2670         VARIANT vt;
2671         VariantInit (&vt);
2672         func (VT_I8, &vt);
2673         if (vt.vt == VT_I8 && vt.llVal == -100)
2674                 return 0;
2675         return 1;
2676 }
2677
2678 LIBTEST_API int STDCALL 
2679 mono_test_marshal_variant_out_ulong_unmanaged(VarRefFunc func)
2680 {
2681         VARIANT vt;
2682         VariantInit (&vt);
2683         func (VT_UI8, &vt);
2684         if (vt.vt == VT_UI8 && vt.ullVal == 100)
2685                 return 0;
2686         return 1;
2687 }
2688
2689 LIBTEST_API int STDCALL 
2690 mono_test_marshal_variant_out_float_unmanaged(VarRefFunc func)
2691 {
2692         VARIANT vt;
2693         VariantInit (&vt);
2694         func (VT_R4, &vt);
2695         if (vt.vt == VT_R4 && fabs (vt.fltVal - 3.14f) < 1e-10)
2696                 return 0;
2697         return 1;
2698 }
2699
2700 LIBTEST_API int STDCALL 
2701 mono_test_marshal_variant_out_double_unmanaged(VarRefFunc func)
2702 {
2703         VARIANT vt;
2704         VariantInit (&vt);
2705         func (VT_R8, &vt);
2706         if (vt.vt == VT_R8 && fabs (vt.dblVal - 3.14) < 1e-10)
2707                 return 0;
2708         return 1;
2709 }
2710
2711 LIBTEST_API int STDCALL 
2712 mono_test_marshal_variant_out_bstr_unmanaged(VarRefFunc func)
2713 {
2714         VARIANT vt;
2715         VariantInit (&vt);
2716         func (VT_BSTR, &vt);
2717         if (vt.vt == VT_BSTR && !wcscmp(vt.bstrVal, L"PI"))
2718                 return 0;
2719         return 1;
2720 }
2721
2722 LIBTEST_API int STDCALL 
2723 mono_test_marshal_variant_out_bool_true_unmanaged(VarRefFunc func)
2724 {
2725         VARIANT vt;
2726         VariantInit (&vt);
2727         func (VT_BOOL, &vt);
2728         if (vt.vt == VT_BOOL && vt.boolVal == VARIANT_TRUE)
2729                 return 0;
2730         return 1;
2731 }
2732
2733 LIBTEST_API int STDCALL 
2734 mono_test_marshal_variant_out_bool_false_unmanaged(VarRefFunc func)
2735 {
2736         VARIANT vt;
2737         VariantInit (&vt);
2738         func (VT_BOOL, &vt);
2739         if (vt.vt == VT_BOOL && vt.boolVal == VARIANT_TRUE)
2740                 return 0;
2741         return 1;
2742 }
2743
2744 typedef struct MonoComObject MonoComObject;
2745
2746 typedef struct
2747 {
2748         int (STDCALL *QueryInterface)(MonoComObject* pUnk, gpointer riid, gpointer* ppv);
2749         int (STDCALL *AddRef)(MonoComObject* pUnk);
2750         int (STDCALL *Release)(MonoComObject* pUnk);
2751         int (STDCALL *get_ITest)(MonoComObject* pUnk, MonoComObject* *ppUnk);
2752         int (STDCALL *SByteIn)(MonoComObject* pUnk, char a);
2753         int (STDCALL *ByteIn)(MonoComObject* pUnk, unsigned char a);
2754         int (STDCALL *ShortIn)(MonoComObject* pUnk, short a);
2755         int (STDCALL *UShortIn)(MonoComObject* pUnk, unsigned short a);
2756         int (STDCALL *IntIn)(MonoComObject* pUnk, int a);
2757         int (STDCALL *UIntIn)(MonoComObject* pUnk, unsigned int a);
2758         int (STDCALL *LongIn)(MonoComObject* pUnk, LONGLONG a);
2759         int (STDCALL *ULongIn)(MonoComObject* pUnk, ULONGLONG a);
2760         int (STDCALL *FloatIn)(MonoComObject* pUnk, float a);
2761         int (STDCALL *DoubleIn)(MonoComObject* pUnk, double a);
2762         int (STDCALL *ITestIn)(MonoComObject* pUnk, MonoComObject* pUnk2);
2763         int (STDCALL *ITestOut)(MonoComObject* pUnk, MonoComObject* *ppUnk);
2764 } MonoIUnknown;
2765
2766 struct MonoComObject
2767 {
2768         MonoIUnknown* vtbl;
2769         int m_ref;
2770 };
2771
2772 DEFINE_GUID(IID_ITest, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);
2773 DEFINE_GUID(IID_IMonoUnknown, 0, 0, 0, 0xC0, 0, 0, 0, 0, 0, 0, 0x46);
2774 DEFINE_GUID(IID_IMonoDispatch, 0x00020400, 0, 0, 0xC0, 0, 0, 0, 0, 0, 0, 0x46);
2775
2776 LIBTEST_API int STDCALL
2777 MonoQueryInterface(MonoComObject* pUnk, gpointer riid, gpointer* ppv)
2778 {
2779         *ppv = NULL;
2780         if (!memcmp(riid, &IID_IMonoUnknown, sizeof(GUID))) {
2781                 *ppv = pUnk;
2782                 return S_OK;
2783         }
2784         else if (!memcmp(riid, &IID_ITest, sizeof(GUID))) {
2785                 *ppv = pUnk;
2786                 return S_OK;
2787         }
2788         else if (!memcmp(riid, &IID_IMonoDispatch, sizeof(GUID))) {
2789                 *ppv = pUnk;
2790                 return S_OK;
2791         }
2792         return E_NOINTERFACE;
2793 }
2794
2795 LIBTEST_API int STDCALL 
2796 MonoAddRef(MonoComObject* pUnk)
2797 {
2798         return ++(pUnk->m_ref);
2799 }
2800
2801 LIBTEST_API int STDCALL 
2802 MonoRelease(MonoComObject* pUnk)
2803 {
2804         return --(pUnk->m_ref);
2805 }
2806
2807 LIBTEST_API int STDCALL 
2808 SByteIn(MonoComObject* pUnk, char a)
2809 {
2810         return S_OK;
2811 }
2812
2813 LIBTEST_API int STDCALL 
2814 ByteIn(MonoComObject* pUnk, unsigned char a)
2815 {
2816         return S_OK;
2817 }
2818
2819 LIBTEST_API int STDCALL 
2820 ShortIn(MonoComObject* pUnk, short a)
2821 {
2822         return S_OK;
2823 }
2824
2825 LIBTEST_API int STDCALL 
2826 UShortIn(MonoComObject* pUnk, unsigned short a)
2827 {
2828         return S_OK;
2829 }
2830
2831 LIBTEST_API int STDCALL 
2832 IntIn(MonoComObject* pUnk, int a)
2833 {
2834         return S_OK;
2835 }
2836
2837 LIBTEST_API int STDCALL 
2838 UIntIn(MonoComObject* pUnk, unsigned int a)
2839 {
2840         return S_OK;
2841 }
2842
2843 LIBTEST_API int STDCALL 
2844 LongIn(MonoComObject* pUnk, LONGLONG a)
2845 {
2846         return S_OK;
2847 }
2848
2849 LIBTEST_API int STDCALL 
2850 ULongIn(MonoComObject* pUnk, ULONGLONG a)
2851 {
2852         return S_OK;
2853 }
2854
2855 LIBTEST_API int STDCALL 
2856 FloatIn(MonoComObject* pUnk, float a)
2857 {
2858         return S_OK;
2859 }
2860
2861 LIBTEST_API int STDCALL 
2862 DoubleIn(MonoComObject* pUnk, double a)
2863 {
2864         return S_OK;
2865 }
2866
2867 LIBTEST_API int STDCALL 
2868 ITestIn(MonoComObject* pUnk, MonoComObject *pUnk2)
2869 {
2870         return S_OK;
2871 }
2872
2873 LIBTEST_API int STDCALL 
2874 ITestOut(MonoComObject* pUnk, MonoComObject* *ppUnk)
2875 {
2876         return S_OK;
2877 }
2878
2879 LIBTEST_API int STDCALL 
2880 get_ITest(MonoComObject* pUnk, MonoComObject* *ppUnk)
2881 {
2882         return S_OK;
2883 }
2884
2885 static void create_com_object (MonoComObject** pOut)
2886 {
2887         *pOut = g_new0 (MonoComObject, 1);
2888         (*pOut)->vtbl = g_new0 (MonoIUnknown, 1);
2889
2890         (*pOut)->m_ref = 1;
2891         (*pOut)->vtbl->QueryInterface = MonoQueryInterface;
2892         (*pOut)->vtbl->AddRef = MonoAddRef;
2893         (*pOut)->vtbl->Release = MonoRelease;
2894         (*pOut)->vtbl->SByteIn = SByteIn;
2895         (*pOut)->vtbl->ByteIn = ByteIn;
2896         (*pOut)->vtbl->ShortIn = ShortIn;
2897         (*pOut)->vtbl->UShortIn = UShortIn;
2898         (*pOut)->vtbl->IntIn = IntIn;
2899         (*pOut)->vtbl->UIntIn = UIntIn;
2900         (*pOut)->vtbl->LongIn = LongIn;
2901         (*pOut)->vtbl->ULongIn = ULongIn;
2902         (*pOut)->vtbl->FloatIn = FloatIn;
2903         (*pOut)->vtbl->DoubleIn = DoubleIn;
2904         (*pOut)->vtbl->ITestIn = ITestIn;
2905         (*pOut)->vtbl->ITestOut = ITestOut;
2906         (*pOut)->vtbl->get_ITest = get_ITest;
2907 }
2908
2909 static MonoComObject* same_object = NULL;
2910
2911 LIBTEST_API int STDCALL 
2912 mono_test_marshal_com_object_create(MonoComObject* *pUnk)
2913 {
2914         create_com_object (pUnk);
2915
2916         if (!same_object)
2917                 same_object = *pUnk;
2918
2919         return 0;
2920 }
2921
2922 LIBTEST_API int STDCALL 
2923 mono_test_marshal_com_object_same(MonoComObject* *pUnk)
2924 {
2925         *pUnk = same_object;
2926
2927         return 0;
2928 }
2929
2930 LIBTEST_API int STDCALL 
2931 mono_test_marshal_com_object_destroy(MonoComObject *pUnk)
2932 {
2933         int ref = --(pUnk->m_ref);
2934         g_free(pUnk->vtbl);
2935         g_free(pUnk);
2936
2937         return ref;
2938 }
2939
2940 LIBTEST_API int STDCALL 
2941 mono_test_marshal_com_object_ref_count(MonoComObject *pUnk)
2942 {
2943         return pUnk->m_ref;
2944 }
2945
2946 LIBTEST_API int STDCALL 
2947 mono_test_marshal_ccw_itest (MonoComObject *pUnk)
2948 {
2949         int hr = 0;
2950         MonoComObject* pTest;
2951
2952         if (!pUnk)
2953                 return 1;
2954
2955         hr = pUnk->vtbl->SByteIn (pUnk, -100);
2956         if (hr != 0)
2957                 return 2;
2958         hr = pUnk->vtbl->ByteIn (pUnk, 100);
2959         if (hr != 0)
2960                 return 3;
2961         hr = pUnk->vtbl->ShortIn (pUnk, -100);
2962         if (hr != 0)
2963                 return 4;
2964         hr = pUnk->vtbl->UShortIn (pUnk, 100);
2965         if (hr != 0)
2966                 return 5;
2967         hr = pUnk->vtbl->IntIn (pUnk, -100);
2968         if (hr != 0)
2969                 return 6;
2970         hr = pUnk->vtbl->UIntIn (pUnk, 100);
2971         if (hr != 0)
2972                 return 7;
2973         hr = pUnk->vtbl->LongIn (pUnk, -100);
2974         if (hr != 0)
2975                 return 8;
2976         hr = pUnk->vtbl->ULongIn (pUnk, 100);
2977         if (hr != 0)
2978                 return 9;
2979         hr = pUnk->vtbl->FloatIn (pUnk, 3.14f);
2980         if (hr != 0)
2981                 return 10;
2982         hr = pUnk->vtbl->DoubleIn (pUnk, 3.14);
2983         if (hr != 0)
2984                 return 11;
2985         hr = pUnk->vtbl->ITestIn (pUnk, pUnk);
2986         if (hr != 0)
2987                 return 12;
2988         hr = pUnk->vtbl->ITestOut (pUnk, &pTest);
2989         if (hr != 0)
2990                 return 13;
2991
2992         return 0;
2993 }
2994
2995
2996 #endif //NOT_YET
2997
2998
2999 /*
3000  * mono_method_get_unmanaged_thunk tests
3001  */
3002
3003 #if defined(__GNUC__) && ((defined(__i386__) && (defined(__linux__) || defined (__APPLE__))) || (defined(__ppc__) && defined(__APPLE__)))
3004 #define ALIGN(size) __attribute__ ((aligned(size)))
3005 #else
3006 #define ALIGN(size)
3007 #endif
3008
3009
3010 /* thunks.cs:TestStruct */
3011 typedef struct _TestStruct {
3012         int A;
3013         double B ALIGN(8);  /* align according to  mono's struct layout */
3014 } TestStruct;
3015
3016 /* Searches for mono symbols in all loaded modules */
3017 static gpointer
3018 lookup_mono_symbol (const char *symbol_name)
3019 {
3020         gpointer symbol;
3021         if (g_module_symbol (g_module_open (NULL, G_MODULE_BIND_LAZY), symbol_name, &symbol))
3022                 return symbol;
3023         else
3024                 return NULL;
3025 }
3026
3027 /**
3028  * test_method_thunk:
3029  *
3030  * @test_id: the test number
3031  * @test_method_handle: MonoMethod* of the C# test method
3032  * @create_object_method_handle: MonoMethod* of thunks.cs:Test.CreateObject
3033  */
3034 LIBTEST_API int STDCALL  
3035 test_method_thunk (int test_id, gpointer test_method_handle, gpointer create_object_method_handle)
3036 {
3037         gpointer (*mono_method_get_unmanaged_thunk)(gpointer)
3038                 = lookup_mono_symbol ("mono_method_get_unmanaged_thunk");
3039
3040         gpointer (*mono_string_new_wrapper)(const char *)
3041                 = lookup_mono_symbol ("mono_string_new_wrapper");
3042
3043         char* (*mono_string_to_utf8)(gpointer)
3044                 = lookup_mono_symbol ("mono_string_to_utf8");
3045
3046         gpointer (*mono_object_unbox)(gpointer)
3047                 = lookup_mono_symbol ("mono_object_unbox");
3048
3049         gpointer test_method, ex = NULL;
3050         gpointer (STDCALL *CreateObject)(gpointer*);
3051
3052
3053         if (!mono_method_get_unmanaged_thunk)
3054                 return 1;
3055
3056         test_method =  mono_method_get_unmanaged_thunk (test_method_handle);
3057         if (!test_method)
3058                 return 2;
3059
3060         CreateObject = mono_method_get_unmanaged_thunk (create_object_method_handle);
3061         if (!CreateObject)
3062                 return 3;
3063
3064
3065         switch (test_id) {
3066
3067         case 0: {
3068                 /* thunks.cs:Test.Test0 */
3069                 void (STDCALL *F)(gpointer*) = test_method;
3070                 F (&ex);
3071                 break;
3072         }
3073
3074         case 1: {
3075                 /* thunks.cs:Test.Test1 */
3076                 int (STDCALL *F)(gpointer*) = test_method;
3077                 if (F (&ex) != 42)
3078                         return 4;
3079                 break;
3080         }
3081
3082         case 2: {
3083                 /* thunks.cs:Test.Test2 */
3084                 gpointer (STDCALL *F)(gpointer, gpointer*) = test_method;
3085                 gpointer str = mono_string_new_wrapper ("foo");
3086                 if (str != F (str, &ex))
3087                         return 4;
3088                 break;
3089         }
3090
3091         case 3: {
3092                 /* thunks.cs:Test.Test3 */
3093                 gpointer (STDCALL *F)(gpointer, gpointer, gpointer*);
3094                 gpointer obj;
3095                 gpointer str;
3096
3097                 F = test_method;
3098                 obj = CreateObject (&ex);
3099                 str = mono_string_new_wrapper ("bar");
3100
3101                 if (str != F (obj, str, &ex))
3102                         return 4;
3103                 break;
3104         }
3105
3106         case 4: {
3107                 /* thunks.cs:Test.Test4 */
3108                 int (STDCALL *F)(gpointer, gpointer, int, gpointer*);
3109                 gpointer obj;
3110                 gpointer str;
3111
3112                 F = test_method;
3113                 obj = CreateObject (&ex);
3114                 str = mono_string_new_wrapper ("bar");
3115
3116                 if (42 != F (obj, str, 42, &ex))
3117                         return 4;
3118
3119                 break;
3120         }
3121
3122         case 5: {
3123                 /* thunks.cs:Test.Test5 */
3124                 int (STDCALL *F)(gpointer, gpointer, int, gpointer*);
3125                 gpointer obj;
3126                 gpointer str;
3127
3128                 F = test_method;
3129                 obj = CreateObject (&ex);
3130                 str = mono_string_new_wrapper ("bar");
3131
3132                 F (obj, str, 42, &ex);
3133                 if (!ex)
3134                     return 4;
3135
3136                 break;
3137         }
3138
3139         case 6: {
3140                 /* thunks.cs:Test.Test6 */
3141                 int (STDCALL *F)(gpointer, guint8, gint16, gint32, gint64, float, double,
3142                                  gpointer, gpointer*);
3143                 gpointer obj;
3144                 gpointer str = mono_string_new_wrapper ("Test6");
3145                 int res;
3146
3147                 F = test_method;
3148                 obj = CreateObject (&ex);
3149
3150                 res = F (obj, 254, 32700, -245378, 6789600, 3.1415, 3.1415, str, &ex);
3151                 if (ex)
3152                         return 4;
3153
3154                 if (!res)
3155                         return 5;
3156
3157                 break;
3158         }
3159
3160         case 7: {
3161                 /* thunks.cs:Test.Test7 */
3162                 gint64 (STDCALL *F)(gpointer*) = test_method;
3163                 if (F (&ex) != G_MAXINT64)
3164                         return 4;
3165                 break;
3166         }
3167
3168         case 8: {
3169                 /* thunks.cs:Test.Test8 */
3170                 void (STDCALL *F)(guint8*, gint16*, gint32*, gint64*, float*, double*,
3171                                  gpointer*, gpointer*);
3172
3173                 guint8 a1;
3174                 gint16 a2;
3175                 gint32 a3;
3176                 gint64 a4;
3177                 float a5;
3178                 double a6;
3179                 gpointer a7;
3180
3181                 F = test_method;
3182
3183                 F (&a1, &a2, &a3, &a4, &a5, &a6, &a7, &ex);
3184                 if (ex)
3185                         return 4;
3186
3187                 if (!(a1 == 254 &&
3188                       a2 == 32700 &&
3189                       a3 == -245378 &&
3190                       a4 == 6789600 &&
3191                       (fabs (a5 - 3.1415) < 0.001) &&
3192                       (fabs (a6 - 3.1415) < 0.001) &&
3193                       strcmp (mono_string_to_utf8 (a7), "Test8") == 0))
3194                         return 5;
3195
3196                 break;
3197         }
3198
3199         case 9: {
3200                 /* thunks.cs:Test.Test9 */
3201                 void (STDCALL *F)(guint8*, gint16*, gint32*, gint64*, float*, double*,
3202                                  gpointer*, gpointer*);
3203
3204                 guint8 a1;
3205                 gint16 a2;
3206                 gint32 a3;
3207                 gint64 a4;
3208                 float a5;
3209                 double a6;
3210                 gpointer a7;
3211
3212                 F = test_method;
3213
3214                 F (&a1, &a2, &a3, &a4, &a5, &a6, &a7, &ex);
3215                 if (!ex)
3216                         return 4;
3217
3218                 break;
3219         }
3220
3221         case 10: {
3222                 /* thunks.cs:Test.Test10 */
3223                 void (STDCALL *F)(gpointer*, gpointer*);
3224
3225                 gpointer obj1, obj2;
3226
3227                 obj1 = obj2 = CreateObject (&ex);
3228                 if (ex)
3229                         return 4;
3230
3231                 F = test_method;
3232
3233                 F (&obj1, &ex);
3234                 if (ex)
3235                         return 5;
3236
3237                 if (obj1 == obj2)
3238                         return 6;
3239
3240                 break;
3241         }
3242
3243         case 100: {
3244                 /* thunks.cs:TestStruct.Test0 */
3245                 int (STDCALL *F)(gpointer*, gpointer*);
3246
3247                 gpointer obj;
3248                 TestStruct *a1;
3249                 int res;
3250
3251                 obj = CreateObject (&ex);
3252                 if (ex)
3253                         return 4;
3254
3255                 if (!obj)
3256                         return 5;
3257
3258                 a1 = mono_object_unbox (obj);
3259                 if (!a1)
3260                         return 6;
3261
3262                 a1->A = 42;
3263                 a1->B = 3.1415;
3264
3265                 F = test_method;
3266
3267                 res = F (obj, &ex);
3268                 if (ex)
3269                         return 7;
3270
3271                 if (!res)
3272                         return 8;
3273
3274                 /* check whether the call was really by value */
3275                 if (a1->A != 42 || a1->B != 3.1415)
3276                         return 9;
3277
3278                 break;
3279         }
3280
3281         case 101: {
3282                 /* thunks.cs:TestStruct.Test1 */
3283                 void (STDCALL *F)(gpointer, gpointer*);
3284
3285                 TestStruct *a1;
3286                 gpointer obj;
3287
3288                 obj = CreateObject (&ex);
3289                 if (ex)
3290                         return 4;
3291
3292                 if (!obj)
3293                         return 5;
3294
3295                 a1 = mono_object_unbox (obj);
3296                 if (!a1)
3297                         return 6;
3298
3299                 F = test_method;
3300
3301                 F (obj, &ex);
3302                 if (ex)
3303                         return 7;
3304
3305                 if (a1->A != 42)
3306                         return 8;
3307
3308                 if (!fabs (a1->B - 3.1415) < 0.001)
3309                         return 9;
3310
3311                 break;
3312         }
3313
3314         case 102: {
3315                 /* thunks.cs:TestStruct.Test2 */
3316                 gpointer (STDCALL *F)(gpointer*);
3317
3318                 TestStruct *a1;
3319                 gpointer obj;
3320
3321                 F = test_method;
3322
3323                 obj = F (&ex);
3324                 if (ex)
3325                         return 4;
3326
3327                 if (!obj)
3328                         return 5;
3329
3330                 a1 = mono_object_unbox (obj);
3331
3332                 if (a1->A != 42)
3333                         return 5;
3334
3335                 if (!fabs (a1->B - 3.1415) < 0.001)
3336                         return 6;
3337
3338                 break;
3339         }
3340
3341         case 103: {
3342                 /* thunks.cs:TestStruct.Test3 */
3343                 void (STDCALL *F)(gpointer, gpointer*);
3344
3345                 TestStruct *a1;
3346                 gpointer obj;
3347
3348                 obj = CreateObject (&ex);
3349                 if (ex)
3350                         return 4;
3351
3352                 if (!obj)
3353                         return 5;
3354                 
3355                 a1 = mono_object_unbox (obj);
3356
3357                 if (!a1)
3358                         return 6;
3359
3360                 a1->A = 42;
3361                 a1->B = 3.1415;
3362
3363                 F = test_method;
3364
3365                 F (obj, &ex);
3366                 if (ex)
3367                         return 4;
3368
3369                 if (a1->A != 1)
3370                         return 5;
3371
3372                 if (a1->B != 17)
3373                         return 6;
3374
3375                 break;
3376         }
3377
3378         default:
3379                 return 9;
3380
3381         }
3382
3383         return 0;
3384 }
3385
3386 typedef struct 
3387 {
3388         char a;
3389 } winx64_struct1;
3390
3391 LIBTEST_API int STDCALL  
3392 mono_test_Winx64_struct1_in (winx64_struct1 var)
3393 {
3394         if (var.a != 123)
3395                 return 1;
3396         return 0;
3397 }
3398
3399 typedef struct
3400 {
3401         char a;
3402         char b;
3403 } winx64_struct2;
3404
3405 LIBTEST_API int STDCALL  
3406 mono_test_Winx64_struct2_in (winx64_struct2 var)
3407 {
3408         if (var.a != 4)
3409                 return 1;
3410         if (var.b != 5)
3411                 return 2;
3412         return 0;
3413 }
3414
3415
3416 typedef struct
3417 {
3418         char a;
3419         char b;
3420         short c;
3421 } winx64_struct3;
3422
3423 LIBTEST_API int STDCALL  
3424 mono_test_Winx64_struct3_in (winx64_struct3 var)
3425 {
3426         if (var.a != 4)
3427                 return 1;
3428         if (var.b != 5)
3429                 return 2;
3430         if (var.c != 0x1234)
3431                 return 3;
3432         return 0;
3433 }
3434
3435 typedef struct
3436 {
3437         char a;
3438         char b;
3439         short c;
3440         unsigned int d;
3441 } winx64_struct4;
3442
3443 LIBTEST_API int STDCALL  
3444 mono_test_Winx64_struct4_in (winx64_struct4 var)
3445 {
3446         if (var.a != 4)
3447                 return 1;
3448         if (var.b != 5)
3449                 return 2;
3450         if (var.c != 0x1234)
3451                 return 3;
3452         if (var.d != 0x87654321)
3453                 return 4;
3454         return 0;
3455 }
3456
3457 typedef struct
3458 {
3459         char a;
3460         char b;
3461         char c;
3462 } winx64_struct5;
3463
3464 LIBTEST_API int STDCALL  
3465 mono_test_Winx64_struct5_in (winx64_struct5 var)
3466 {
3467         if (var.a != 4)
3468                 return 1;
3469         if (var.b != 5)
3470                 return 2;
3471         if (var.c != 6)
3472                 return 3;
3473         return 0;
3474 }
3475
3476 typedef struct
3477 {
3478         winx64_struct1 a;
3479         short b;
3480         char c;
3481 } winx64_struct6;
3482
3483 LIBTEST_API int STDCALL  
3484 mono_test_Winx64_struct6_in (winx64_struct6 var)
3485 {
3486         if (var.a.a != 4)
3487                 return 1;
3488         if (var.b != 5)
3489                 return 2;
3490         if (var.c != 6)
3491                 return 3;
3492         return 0;
3493 }
3494
3495 LIBTEST_API int STDCALL  
3496 mono_test_Winx64_structs_in1 (winx64_struct1 var1,
3497                          winx64_struct2 var2,
3498                          winx64_struct3 var3,
3499                          winx64_struct4 var4)
3500 {
3501         if (var1.a != 123)
3502                 return 1;
3503         
3504         if (var2.a != 4)
3505                 return 2;
3506         if (var2.b != 5)
3507                 return 3;
3508         
3509         if (var3.a != 4)
3510                 return 4;
3511         if (var3.b != 5)
3512                 return 2;
3513         if (var3.c != 0x1234)
3514                 return 5;
3515         
3516         if (var4.a != 4)
3517                 return 6;
3518         if (var4.b != 5)
3519                 return 7;
3520         if (var4.c != 0x1234)
3521                 return 8;
3522         if (var4.d != 0x87654321)
3523                 return 9;
3524         return 0;
3525 }
3526
3527 LIBTEST_API int STDCALL  
3528 mono_test_Winx64_structs_in2 (winx64_struct1 var1,
3529                          winx64_struct1 var2,
3530                          winx64_struct1 var3,
3531                          winx64_struct1 var4,
3532                          winx64_struct1 var5)
3533 {
3534         if (var1.a != 1)
3535                 return 1;
3536         if (var2.a != 2)
3537                 return 2;
3538         if (var3.a != 3)
3539                 return 3;
3540         if (var4.a != 4)
3541                 return 4;
3542         if (var5.a != 5)
3543                 return 5;
3544         
3545         return 0;
3546 }
3547
3548 LIBTEST_API int STDCALL  
3549 mono_test_Winx64_structs_in3 (winx64_struct1 var1,
3550                          winx64_struct5 var2,
3551                          winx64_struct1 var3,
3552                          winx64_struct5 var4,
3553                          winx64_struct1 var5,
3554                          winx64_struct5 var6)
3555 {
3556         if (var1.a != 1)
3557                 return 1;
3558         
3559         if (var2.a != 2)
3560                 return 2;
3561         if (var2.b != 3)
3562                 return 2;
3563         if (var2.c != 4)
3564                 return 4;
3565         
3566         if (var3.a != 5)
3567                 return 5;
3568         
3569         if (var4.a != 6)
3570                 return 6;
3571         if (var4.b != 7)
3572                 return 7;
3573         if (var4.c != 8)
3574                 return 8;
3575         
3576         if (var5.a != 9)
3577                 return 9;
3578
3579         if (var6.a != 10)
3580                 return 10;
3581         if (var6.b != 11)
3582                 return 11;
3583         if (var6.c != 12)
3584                 return 12;
3585         
3586         return 0;
3587 }
3588
3589 LIBTEST_API winx64_struct1 STDCALL  
3590 mono_test_Winx64_struct1_ret (void)
3591 {
3592         winx64_struct1 ret;
3593         ret.a = 123;
3594         return ret;
3595 }
3596
3597 LIBTEST_API winx64_struct2 STDCALL  
3598 mono_test_Winx64_struct2_ret (void)
3599 {
3600         winx64_struct2 ret;
3601         ret.a = 4;
3602         ret.b = 5;
3603         return ret;
3604 }
3605
3606 LIBTEST_API winx64_struct3 STDCALL  
3607 mono_test_Winx64_struct3_ret (void)
3608 {
3609         winx64_struct3 ret;
3610         ret.a = 4;
3611         ret.b = 5;
3612         ret.c = 0x1234;
3613         return ret;
3614 }
3615
3616 LIBTEST_API winx64_struct4 STDCALL  
3617 mono_test_Winx64_struct4_ret (void)
3618 {
3619         winx64_struct4 ret;
3620         ret.a = 4;
3621         ret.b = 5;
3622         ret.c = 0x1234;
3623         ret.d = 0x87654321;
3624         return ret;
3625 }
3626
3627 LIBTEST_API winx64_struct5 STDCALL  
3628 mono_test_Winx64_struct5_ret (void)
3629 {
3630         winx64_struct5 ret;
3631         ret.a = 4;
3632         ret.b = 5;
3633         ret.c = 6;
3634         return ret;
3635 }
3636
3637 LIBTEST_API winx64_struct1 STDCALL  
3638 mono_test_Winx64_struct1_ret_5_args (char a, char b, char c, char d, char e)
3639 {
3640         winx64_struct1 ret;
3641         ret.a = a + b + c + d + e;
3642         return ret;
3643 }
3644
3645 LIBTEST_API winx64_struct5 STDCALL
3646 mono_test_Winx64_struct5_ret6_args (char a, char b, char c, char d, char e)
3647 {
3648         winx64_struct5 ret;
3649         ret.a = a + b;
3650         ret.b = c + d;
3651         ret.c = e;
3652         return ret;
3653 }
3654
3655 typedef struct
3656 {
3657         float a;
3658         float b;
3659 } winx64_floatStruct;
3660
3661 LIBTEST_API int STDCALL  
3662 mono_test_Winx64_floatStruct (winx64_floatStruct a)
3663 {
3664         if (a.a > 5.6 || a.a < 5.4)
3665                 return 1;
3666
3667         if (a.b > 9.6 || a.b < 9.4)
3668                 return 2;
3669         
3670         return 0;
3671 }
3672
3673 typedef struct
3674 {
3675         double a;
3676 } winx64_doubleStruct;
3677
3678 LIBTEST_API int STDCALL  
3679 mono_test_Winx64_doubleStruct (winx64_doubleStruct a)
3680 {
3681         if (a.a > 5.6 || a.a < 5.4)
3682                 return 1;
3683         
3684         return 0;
3685 }
3686
3687 typedef int (STDCALL *managed_struct1_delegate) (winx64_struct1 a);
3688
3689 LIBTEST_API int STDCALL 
3690 mono_test_managed_Winx64_struct1_in(managed_struct1_delegate func)
3691 {
3692         winx64_struct1 val;
3693         val.a = 5;
3694         return func (val);
3695 }
3696
3697 typedef int (STDCALL *managed_struct5_delegate) (winx64_struct5 a);
3698
3699 LIBTEST_API int STDCALL 
3700 mono_test_managed_Winx64_struct5_in(managed_struct5_delegate func)
3701 {
3702         winx64_struct5 val;
3703         val.a = 5;
3704         val.b = 0x10;
3705         val.c = 0x99;
3706         return func (val);
3707 }
3708
3709 typedef int (STDCALL *managed_struct1_struct5_delegate) (winx64_struct1 a, winx64_struct5 b,
3710                                                          winx64_struct1 c, winx64_struct5 d,
3711                                                          winx64_struct1 e, winx64_struct5 f);
3712
3713 LIBTEST_API int STDCALL 
3714 mono_test_managed_Winx64_struct1_struct5_in(managed_struct1_struct5_delegate func)
3715 {
3716         winx64_struct1 a, c, e;
3717         winx64_struct5 b, d, f;
3718         a.a = 1;
3719         b.a = 2; b.b = 3; b.c = 4;
3720         c.a = 5;
3721         d.a = 6; d.b = 7; d.c = 8;
3722         e.a = 9;
3723         f.a = 10; f.b = 11; f.c = 12;
3724
3725         return func (a, b, c, d, e, f);
3726 }
3727
3728 typedef winx64_struct1 (STDCALL *managed_struct1_ret_delegate) (void);
3729
3730 LIBTEST_API int STDCALL 
3731 mono_test_Winx64_struct1_ret_managed (managed_struct1_ret_delegate func)
3732 {
3733         winx64_struct1 ret;
3734
3735         ret = func ();
3736
3737         if (ret.a != 0x45)
3738                 return 1;
3739         
3740         return 0;
3741 }
3742
3743 typedef winx64_struct5 (STDCALL *managed_struct5_ret_delegate) (void);
3744
3745 LIBTEST_API int STDCALL 
3746 mono_test_Winx64_struct5_ret_managed (managed_struct5_ret_delegate func)
3747 {
3748         winx64_struct5 ret;
3749
3750         ret = func ();
3751
3752         if (ret.a != 0x12)
3753                 return 1;
3754         if (ret.b != 0x34)
3755                 return 2;
3756         if (ret.c != 0x56)
3757                 return 3;
3758         
3759         return 0;
3760 }
3761
3762 LIBTEST_API int STDCALL 
3763 mono_test_marshal_bool_in (int arg, unsigned int expected, unsigned int bDefaultMarsh, unsigned int bBoolCustMarsh,
3764                            char bI1CustMarsh, unsigned char bU1CustMarsh, unsigned short bVBCustMarsh)
3765 {
3766         switch (arg) {
3767         case 1: 
3768                 if (bDefaultMarsh != expected)
3769                         return 1;
3770                 break;
3771         case 2: 
3772                 if (bBoolCustMarsh != expected)
3773                         return 2;
3774                 break;
3775         case 3: 
3776                 if (bI1CustMarsh != expected)
3777                         return 3;
3778                 break;
3779         case 4: 
3780                 if (bU1CustMarsh != expected)
3781                         return 4;
3782                 break;
3783         case 5: 
3784                 if (bVBCustMarsh != expected)
3785                         return 5;
3786                 break;
3787         default:
3788                 return 999;             
3789         }
3790         return 0;
3791 }
3792
3793 LIBTEST_API int STDCALL 
3794 mono_test_marshal_bool_out (int arg, unsigned int testVal, unsigned int* bDefaultMarsh, unsigned int* bBoolCustMarsh,
3795                            char* bI1CustMarsh, unsigned char* bU1CustMarsh, unsigned short* bVBCustMarsh)
3796 {
3797         switch (arg) {
3798         case 1: 
3799                 if (!bDefaultMarsh)
3800                         return 1;
3801                 *bDefaultMarsh = testVal;
3802                 break;  
3803         case 2: 
3804                 if (!bBoolCustMarsh)
3805                         return 2;
3806                 *bBoolCustMarsh = testVal;
3807                 break;  
3808         case 3: 
3809                 if (!bI1CustMarsh)
3810                         return 3;
3811                 *bI1CustMarsh = (char)testVal;
3812                 break;  
3813         case 4: 
3814                 if (!bU1CustMarsh)
3815                         return 4;
3816                 *bU1CustMarsh = (unsigned char)testVal;
3817                 break;  
3818         case 5: 
3819                 if (!bVBCustMarsh)
3820                         return 5;
3821                 *bVBCustMarsh = (unsigned short)testVal;
3822                 break;  
3823         default:
3824                 return 999;
3825         }
3826         return 0;
3827 }
3828
3829 LIBTEST_API int STDCALL 
3830 mono_test_marshal_bool_ref (int arg, unsigned int expected, unsigned int testVal, unsigned int* bDefaultMarsh,
3831                             unsigned int* bBoolCustMarsh, char* bI1CustMarsh, unsigned char* bU1CustMarsh, 
3832                             unsigned short* bVBCustMarsh)
3833 {
3834         switch (arg) {
3835         case 1: 
3836                 if (!bDefaultMarsh)
3837                         return 1;
3838                 if (*bDefaultMarsh != expected)
3839                         return 2;
3840                 *bDefaultMarsh = testVal;
3841                 break;
3842         case 2: 
3843                 if (!bBoolCustMarsh)
3844                         return 3;
3845                 if (*bBoolCustMarsh != expected)
3846                         return 4;
3847                 *bBoolCustMarsh = testVal;
3848                 break;
3849         case 3: 
3850                 if (!bI1CustMarsh)
3851                         return 5;
3852                 if (*bI1CustMarsh != expected)
3853                         return 6;
3854                 *bI1CustMarsh = (char)testVal;
3855                 break;
3856         case 4: 
3857                 if (!bU1CustMarsh)
3858                         return 7;
3859                 if (*bU1CustMarsh != expected)
3860                         return 8;
3861                 *bU1CustMarsh = (unsigned char)testVal;
3862                 break;
3863         case 5: 
3864                 if (!bVBCustMarsh)
3865                         return 9;
3866                 if (*bVBCustMarsh != expected)
3867                         return 10;
3868                 *bVBCustMarsh = (unsigned short)testVal;
3869                 break;
3870         default:
3871                 return 999;             
3872         }
3873         return 0;
3874 }
3875
3876
3877 typedef int (STDCALL *MarshalBoolInDelegate) (int arg, unsigned int expected, unsigned int bDefaultMarsh,
3878         unsigned int bBoolCustMarsh, char bI1CustMarsh, unsigned char bU1CustMarsh, unsigned short bVBCustMarsh);
3879
3880 LIBTEST_API int STDCALL 
3881 mono_test_managed_marshal_bool_in (int arg, unsigned int expected, unsigned int testVal, MarshalBoolInDelegate pfcn)
3882 {
3883         if (!pfcn)
3884                 return 0x9900;
3885
3886         switch (arg) {
3887         case 1:
3888                 return pfcn (arg, expected, testVal, 0, 0, 0, 0);
3889         case 2:
3890                 return pfcn (arg, expected, 0, testVal,  0, 0, 0);
3891         case 3:
3892                 return pfcn (arg, expected, 0, 0, testVal, 0, 0);
3893         case 4:
3894                 return pfcn (arg, expected, 0, 0, 0, testVal, 0);
3895         case 5:
3896                 return pfcn (arg, expected, 0, 0, 0, 0, testVal);
3897         default:
3898                 return 0x9800;
3899         }
3900
3901         return 0;
3902 }
3903
3904 typedef int (STDCALL *MarshalBoolOutDelegate) (int arg, unsigned int expected, unsigned int* bDefaultMarsh,
3905         unsigned int* bBoolCustMarsh, char* bI1CustMarsh, unsigned char* bU1CustMarsh, unsigned short* bVBCustMarsh);
3906
3907 LIBTEST_API int STDCALL 
3908 mono_test_managed_marshal_bool_out (int arg, unsigned int expected, unsigned int testVal, MarshalBoolOutDelegate pfcn)
3909 {
3910         int ret;
3911         unsigned int lDefaultMarsh, lBoolCustMarsh;
3912         char lI1CustMarsh = 0;
3913         unsigned char lU1CustMarsh = 0;
3914         unsigned short lVBCustMarsh = 0;
3915         lDefaultMarsh = lBoolCustMarsh = 0;
3916
3917         if (!pfcn)
3918                 return 0x9900;
3919
3920         switch (arg) {
3921         case 1: {
3922                 unsigned int ltVal = 0;
3923                 ret = pfcn (arg, testVal, &ltVal, &lBoolCustMarsh, &lI1CustMarsh, &lU1CustMarsh, &lVBCustMarsh);
3924                 if (ret)
3925                         return 0x0100 + ret;
3926                 if (expected != ltVal)
3927                         return 0x0200;
3928                 break;
3929         }
3930         case 2: {
3931                 unsigned int ltVal = 0;
3932                 ret = pfcn (arg, testVal, &lDefaultMarsh, &ltVal, &lI1CustMarsh, &lU1CustMarsh, &lVBCustMarsh);
3933                 if (ret)
3934                         return 0x0300 + ret;
3935                 if (expected != ltVal)
3936                         return 0x0400;
3937                 break;
3938         }
3939         case 3: {
3940                 char ltVal = 0;
3941                 ret = pfcn (arg, testVal, &lDefaultMarsh, &lBoolCustMarsh, &ltVal, &lU1CustMarsh, &lVBCustMarsh);
3942                 if (ret)
3943                         return 0x0500 + ret;
3944                 if (expected != ltVal)
3945                         return 0x0600;
3946                 break;
3947         }
3948         case 4: {
3949                 unsigned char ltVal = 0;
3950                 ret = pfcn (arg, testVal, &lDefaultMarsh, &lBoolCustMarsh, &lI1CustMarsh, &ltVal, &lVBCustMarsh);
3951                 if (ret)
3952                         return 0x0700 + ret;
3953                 if (expected != ltVal)
3954                         return 0x0800;
3955                 break;
3956         }
3957         case 5: {
3958                 unsigned short ltVal = 0;
3959                 ret = pfcn (arg, testVal, &lDefaultMarsh, &lBoolCustMarsh, &lI1CustMarsh, &lU1CustMarsh, &ltVal);
3960                 if (ret)
3961                         return 0x0900 + ret;
3962                 if (expected != ltVal)
3963                         return 0x1000;
3964                 break;
3965         }
3966         default:
3967                 return 0x9800;
3968         }
3969
3970         return 0;
3971 }
3972
3973 typedef int (STDCALL *MarshalBoolRefDelegate) (int arg, unsigned int expected, unsigned int testVal, unsigned int* bDefaultMarsh,
3974         unsigned int* bBoolCustMarsh, char* bI1CustMarsh, unsigned char* bU1CustMarsh, unsigned short* bVBCustMarsh);
3975
3976 LIBTEST_API int STDCALL 
3977 mono_test_managed_marshal_bool_ref (int arg, unsigned int expected, unsigned int testVal, unsigned int outExpected,
3978                                     unsigned int outTestVal, MarshalBoolRefDelegate pfcn)
3979 {
3980         int ret;
3981         unsigned int lDefaultMarsh, lBoolCustMarsh;
3982         char lI1CustMarsh = 0;
3983         unsigned char lU1CustMarsh = 0;
3984         unsigned short lVBCustMarsh = 0;
3985         lDefaultMarsh = lBoolCustMarsh = 0;
3986
3987         if (!pfcn)
3988                 return 0x9900;
3989
3990         switch (arg) {
3991         case 1:
3992         {
3993                 unsigned int ltestVal = testVal;
3994                 ret = pfcn (arg, expected, outTestVal, &ltestVal, &lBoolCustMarsh, &lI1CustMarsh, &lU1CustMarsh, &lVBCustMarsh);
3995                 if (ret)
3996                         return 0x0100 + ret;
3997                 if (outExpected != ltestVal)
3998                         return 0x0200;
3999                 break;
4000         }
4001         case 2:
4002         {
4003                 unsigned int ltestVal = testVal;
4004                 ret = pfcn (arg, expected, outTestVal, &lDefaultMarsh, &ltestVal, &lI1CustMarsh, &lU1CustMarsh, &lVBCustMarsh);
4005                 if (ret)
4006                         return 0x0300 + ret;
4007                 if (outExpected != ltestVal)
4008                         return 0x0400;
4009                 break;
4010         }
4011         case 3:
4012         {
4013                 char ltestVal = testVal;
4014                 ret = pfcn (arg, expected, outTestVal, &lDefaultMarsh, &lBoolCustMarsh, &ltestVal, &lU1CustMarsh, &lVBCustMarsh);
4015                 if (ret)
4016                         return 0x0500 + ret;
4017                 if (outExpected != ltestVal)
4018                         return 0x0600;
4019                 break;
4020         }
4021         case 4:
4022         {
4023                 unsigned char ltestVal = testVal;
4024                 ret = pfcn (arg, expected, outTestVal, &lDefaultMarsh, &lBoolCustMarsh, &lI1CustMarsh, &ltestVal, &lVBCustMarsh);
4025                 if (ret)
4026                         return 0x0700 + ret;
4027                 if (outExpected != ltestVal)
4028                         return 0x0800;
4029                 break;
4030         }
4031         case 5:
4032         {
4033                 unsigned short ltestVal = testVal;
4034                 ret = pfcn (arg, expected, outTestVal, &lDefaultMarsh, &lBoolCustMarsh, &lI1CustMarsh, &lU1CustMarsh, &ltestVal);
4035                 if (ret)
4036                         return 0x0900 + ret;
4037                 if (outExpected != ltestVal)
4038                         return 0x1000;
4039                 break;
4040         }
4041         default:
4042                 return 0x9800;
4043         }
4044
4045         return 0;
4046 }
4047
4048