[tests] Test loading references from LoadFrom and LoadFile contexts
[mono-project.git] / mono / tests / libtest.c
bloba43846ad7605ffbf73caa0e5311eec752e36c867
1 #include <config.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <glib.h>
6 #include <gmodule.h>
7 #include <errno.h>
8 #include <time.h>
9 #include <math.h>
10 #include <setjmp.h>
12 #ifdef WIN32
13 #include <windows.h>
14 #include "initguid.h"
15 #else
16 #include <pthread.h>
17 #endif
19 #ifdef WIN32
20 #define STDCALL __stdcall
21 #else
22 #define STDCALL
23 #endif
25 #ifdef __GNUC__
26 #pragma GCC diagnostic ignored "-Wmissing-prototypes"
27 #endif
29 #ifdef WIN32
30 extern __declspec(dllimport) void __stdcall CoTaskMemFree(void *ptr);
31 #endif
33 typedef int (STDCALL *SimpleDelegate) (int a);
35 #if defined(WIN32) && defined (_MSC_VER)
36 #define LIBTEST_API __declspec(dllexport)
37 #elif defined(__GNUC__)
38 #define LIBTEST_API __attribute__ ((__visibility__ ("default")))
39 #else
40 #define LIBTEST_API
41 #endif
43 static void marshal_free (void *ptr)
45 #ifdef WIN32
46 CoTaskMemFree (ptr);
47 #else
48 g_free (ptr);
49 #endif
52 static void* marshal_alloc (gsize size)
54 #ifdef WIN32
55 return CoTaskMemAlloc (size);
56 #else
57 return g_malloc (size);
58 #endif
61 static void* marshal_alloc0 (gsize size)
63 #ifdef WIN32
64 void* ptr = CoTaskMemAlloc (size);
65 memset(ptr, 0, size);
66 return ptr;
67 #else
68 return g_malloc0 (size);
69 #endif
72 static char* marshal_strdup (const char *str)
74 #ifdef WIN32
75 int len;
76 char *buf;
78 if (!str)
79 return NULL;
81 len = strlen (str);
82 buf = (char *) CoTaskMemAlloc (len + 1);
83 return strcpy (buf, str);
84 #else
85 return g_strdup (str);
86 #endif
89 static gunichar2* marshal_bstr_alloc(const gchar* str)
91 #ifdef WIN32
92 gunichar2* ret = NULL;
93 gunichar2* temp = NULL;
94 temp = g_utf8_to_utf16 (str, -1, NULL, NULL, NULL);
95 ret = SysAllocString (temp);
96 g_free (temp);
97 return ret;
98 #else
99 gchar* ret = NULL;
100 int slen = strlen (str);
101 gunichar2* temp;
102 /* allocate len + 1 utf16 characters plus 4 byte integer for length*/
103 ret = (gchar *)g_malloc ((slen + 1) * sizeof(gunichar2) + sizeof(guint32));
104 if (ret == NULL)
105 return NULL;
106 temp = g_utf8_to_utf16 (str, -1, NULL, NULL, NULL);
107 memcpy (ret + sizeof(guint32), temp, slen * sizeof(gunichar2));
108 * ((guint32 *) ret) = slen * sizeof(gunichar2);
109 ret [4 + slen * sizeof(gunichar2)] = 0;
110 ret [5 + slen * sizeof(gunichar2)] = 0;
112 return (gunichar2*)(ret + 4);
113 #endif
116 #define marshal_new0(type,size) ((type *) marshal_alloc0 (sizeof (type)* (size)))
118 LIBTEST_API int STDCALL
119 mono_cominterop_is_supported (void)
121 #if defined(TARGET_X86) || defined(TARGET_AMD64)
122 return 1;
123 #endif
124 return 0;
127 LIBTEST_API unsigned short* STDCALL
128 test_lpwstr_marshal (unsigned short* chars, long length)
130 int i = 0;
131 unsigned short *res;
133 res = (unsigned short *)marshal_alloc (2 * (length + 1));
135 // printf("test_lpwstr_marshal()\n");
137 while ( i < length ) {
138 // printf("X|%u|\n", chars[i]);
139 res [i] = chars[i];
140 i++;
143 res [i] = 0;
145 return res;
149 LIBTEST_API void STDCALL
150 test_lpwstr_marshal_out (unsigned short** chars)
152 int i = 0;
153 const char abc[] = "ABC";
154 glong len = strlen(abc);
156 *chars = (unsigned short *)marshal_alloc (2 * (len + 1));
158 while ( i < len ) {
159 (*chars) [i] = abc[i];
160 i++;
163 (*chars) [i] = 0;
166 typedef struct {
167 int b;
168 int a;
169 int c;
170 } union_test_1_type;
172 LIBTEST_API int STDCALL
173 mono_union_test_1 (union_test_1_type u1) {
174 // printf ("Got values %d %d %d\n", u1.b, u1.a, u1.c);
175 return u1.a + u1.b + u1.c;
178 LIBTEST_API int STDCALL
179 mono_return_int (int a) {
180 // printf ("Got value %d\n", a);
181 return a;
184 LIBTEST_API float STDCALL
185 mono_test_marshal_pass_return_float (float f) {
186 return f + 1.0;
189 struct ss
191 int i;
194 LIBTEST_API int STDCALL
195 mono_return_int_ss (struct ss a) {
196 // printf ("Got value %d\n", a.i);
197 return a.i;
200 LIBTEST_API struct ss STDCALL
201 mono_return_ss (struct ss a) {
202 // printf ("Got value %d\n", a.i);
203 a.i++;
204 return a;
207 struct sc1
209 char c[1];
212 LIBTEST_API struct sc1 STDCALL
213 mono_return_sc1 (struct sc1 a) {
214 // printf ("Got value %d\n", a.c[0]);
215 a.c[0]++;
216 return a;
220 struct sc3
222 char c[3];
225 LIBTEST_API struct sc3 STDCALL
226 mono_return_sc3 (struct sc3 a) {
227 // printf ("Got values %d %d %d\n", a.c[0], a.c[1], a.c[2]);
228 a.c[0]++;
229 a.c[1] += 2;
230 a.c[2] += 3;
231 return a;
234 struct sc5
236 char c[5];
239 LIBTEST_API struct sc5 STDCALL
240 mono_return_sc5 (struct sc5 a) {
241 // printf ("Got values %d %d %d %d %d\n", a.c[0], a.c[1], a.c[2], a.c[3], a.c[4]);
242 a.c[0]++;
243 a.c[1] += 2;
244 a.c[2] += 3;
245 a.c[3] += 4;
246 a.c[4] += 5;
247 return a;
250 union su
252 int i1;
253 int i2;
256 LIBTEST_API int STDCALL
257 mono_return_int_su (union su a) {
258 // printf ("Got value %d\n", a.i1);
259 return a.i1;
262 struct FI {
263 float f1;
264 float f2;
265 float f3;
268 struct NestedFloat {
269 struct FI fi;
270 float f4;
273 LIBTEST_API struct NestedFloat STDCALL
274 mono_return_nested_float (void)
276 struct NestedFloat f;
277 f.fi.f1 = 1.0;
278 f.fi.f2 = 2.0;
279 f.fi.f3 = 3.0;
280 f.f4 = 4.0;
281 return f;
284 struct Scalar4 {
285 double val[4];
288 struct Rect {
289 int x;
290 int y;
291 int width;
292 int height;
295 LIBTEST_API char * STDCALL
296 mono_return_struct_4_double (void *ptr, struct Rect rect, struct Scalar4 sc4, int a, int b, int c)
298 char *buffer = (char *) malloc (1024 * sizeof (char));
299 sprintf (buffer, "sc4 = {%.1f, %.1f, %.1f, %.1f }, a=%x, b=%x, c=%x\n", (float) sc4.val [0], (float) sc4.val [1], (float) sc4.val [2], (float) sc4.val [3], a, b, c);
300 return buffer;
303 LIBTEST_API int STDCALL
304 mono_test_many_int_arguments (int a, int b, int c, int d, int e,
305 int f, int g, int h, int i, int j);
306 LIBTEST_API short STDCALL
307 mono_test_many_short_arguments (short a, short b, short c, short d, short e,
308 short f, short g, short h, short i, short j);
309 LIBTEST_API char STDCALL
310 mono_test_many_char_arguments (char a, char b, char c, char d, char e,
311 char f, char g, char h, char i, char j);
313 LIBTEST_API int STDCALL
314 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)
316 return a + b + c + d + e + f + g + h + i + j;
319 LIBTEST_API short STDCALL
320 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)
322 return a + b + c + d + e + f + g + h + i + j;
325 LIBTEST_API char STDCALL
326 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)
328 return a + b + c + d + e + f + g + h + i + j;
331 LIBTEST_API float STDCALL
332 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)
334 return a + b + c + d + e + f + g + h + i + j;
337 LIBTEST_API double STDCALL
338 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)
340 return a + b + c + d + e + f + g + h + i + j;
343 LIBTEST_API double STDCALL
344 mono_test_split_double_arguments (double a, double b, float c, double d, double e)
346 return a + b + c + d + e;
349 LIBTEST_API int STDCALL
350 mono_test_puts_static (char *s)
352 // printf ("TEST %s\n", s);
353 return 1;
356 typedef int (STDCALL *SimpleDelegate3) (int a, int b);
358 LIBTEST_API int STDCALL
359 mono_invoke_delegate (SimpleDelegate3 delegate)
361 int res;
363 // printf ("start invoke %p\n", delegate);
365 res = delegate (2, 3);
367 // printf ("end invoke\n");
369 return res;
372 LIBTEST_API int STDCALL
373 mono_invoke_simple_delegate (SimpleDelegate d)
375 return d (4);
378 LIBTEST_API int STDCALL
379 mono_test_marshal_char (short a1)
381 if (a1 == 'a')
382 return 0;
384 return 1;
387 LIBTEST_API void STDCALL
388 mono_test_marshal_char_array (gunichar2 *s)
390 const char m[] = "abcdef";
391 gunichar2* s2;
392 glong len;
394 s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
396 len = (len * 2) + 2;
397 memcpy (s, s2, len);
399 g_free (s2);
402 LIBTEST_API int STDCALL
403 mono_test_marshal_ansi_char_array (char *s)
405 const char m[] = "abcdef";
407 if (strncmp ("qwer", s, 4))
408 return 1;
410 memcpy (s, m, sizeof (m));
411 return 0;
414 LIBTEST_API int STDCALL
415 mono_test_marshal_unicode_char_array (gunichar2 *s)
417 const char m[] = "abcdef";
418 const char expected[] = "qwer";
419 gunichar2 *s1, *s2;
420 glong len1, len2;
422 s1 = g_utf8_to_utf16 (m, -1, NULL, &len1, NULL);
423 s2 = g_utf8_to_utf16 (expected, -1, NULL, &len2, NULL);
424 len1 = (len1 * 2);
425 len2 = (len2 * 2);
427 if (memcmp (s, s2, len2))
428 return 1;
430 memcpy (s, s1, len1);
431 return 0;
434 LIBTEST_API int STDCALL
435 mono_test_empty_pinvoke (int i)
437 return i;
440 LIBTEST_API int STDCALL
441 mono_test_marshal_bool_byref (int a, int *b, int c)
443 int res = *b;
445 *b = 1;
447 return res;
450 LIBTEST_API int STDCALL
451 mono_test_marshal_bool_in_as_I1_U1 (char bTrue, char bFalse)
453 if (!bTrue)
454 return 1;
455 if (bFalse)
456 return 2;
457 return 0;
460 LIBTEST_API int STDCALL
461 mono_test_marshal_bool_out_as_I1_U1 (char* bTrue, char* bFalse)
463 if (!bTrue || !bFalse)
464 return 3;
466 *bTrue = 1;
467 *bFalse = 0;
469 return 0;
472 LIBTEST_API int STDCALL
473 mono_test_marshal_bool_ref_as_I1_U1 (char* bTrue, char* bFalse)
475 if (!bTrue || !bFalse)
476 return 4;
478 if (!(*bTrue))
479 return 5;
480 if (*bFalse)
481 return 6;
483 *bFalse = 1;
484 *bTrue = 0;
486 return 0;
489 LIBTEST_API int STDCALL
490 mono_test_marshal_array (int *a1)
492 int i, sum = 0;
494 for (i = 0; i < 50; i++)
495 sum += a1 [i];
497 return sum;
500 LIBTEST_API int STDCALL
501 mono_test_marshal_inout_array (int *a1)
503 int i, sum = 0;
505 for (i = 0; i < 50; i++) {
506 sum += a1 [i];
507 a1 [i] = 50 - a1 [i];
510 return sum;
513 LIBTEST_API int /* cdecl */
514 mono_test_marshal_inout_array_cdecl (int *a1)
516 return mono_test_marshal_inout_array (a1);
519 LIBTEST_API int STDCALL
520 mono_test_marshal_out_array (int *a1)
522 int i;
524 for (i = 0; i < 50; i++) {
525 a1 [i] = i;
528 return 0;
531 LIBTEST_API int STDCALL
532 mono_test_marshal_out_byref_array_out_size_param (int **out_arr, int *out_len)
534 int *arr;
535 int i, len;
537 len = 4;
538 arr = (gint32 *)marshal_alloc (sizeof (gint32) * len);
539 for (i = 0; i < len; ++i)
540 arr [i] = i;
541 *out_arr = arr;
542 *out_len = len;
544 return 0;
547 LIBTEST_API int STDCALL
548 mono_test_marshal_out_lparray_out_size_param (int *arr, int *out_len)
550 int i, len;
552 len = 4;
553 for (i = 0; i < len; ++i)
554 arr [i] = i;
555 *out_len = len;
557 return 0;
560 LIBTEST_API int STDCALL
561 mono_test_marshal_inout_nonblittable_array (gunichar2 *a1)
563 int i, sum = 0;
565 for (i = 0; i < 10; i++) {
566 a1 [i] = 'F';
569 return sum;
572 typedef struct {
573 int a;
574 int b;
575 int c;
576 const char *d;
577 gunichar2 *d2;
578 } simplestruct;
580 typedef struct {
581 double x;
582 double y;
583 } point;
585 LIBTEST_API simplestruct STDCALL
586 mono_test_return_vtype (int i)
588 simplestruct res;
589 static gunichar2 test2 [] = { 'T', 'E', 'S', 'T', '2', 0 };
591 res.a = 0;
592 res.b = 1;
593 res.c = 0;
594 res.d = "TEST";
595 res.d2 = test2;
597 return res;
600 LIBTEST_API void STDCALL
601 mono_test_delegate_struct (void)
603 // printf ("TEST\n");
606 typedef char* (STDCALL *ReturnStringDelegate) (const char *s);
608 LIBTEST_API char * STDCALL
609 mono_test_return_string (ReturnStringDelegate func)
611 char *res;
613 // printf ("mono_test_return_string\n");
615 res = func ("TEST");
616 marshal_free (res);
618 // printf ("got string: %s\n", res);
619 return marshal_strdup ("12345");
622 typedef int (STDCALL *RefVTypeDelegate) (int a, simplestruct *ss, int b);
624 LIBTEST_API int STDCALL
625 mono_test_ref_vtype (int a, simplestruct *ss, int b, RefVTypeDelegate func)
627 if (a == 1 && b == 2 && ss->a == 0 && ss->b == 1 && ss->c == 0 &&
628 !strcmp (ss->d, "TEST1")) {
629 ss->a = 1;
630 ss->b = 0;
631 ss->c = 1;
632 ss->d = "TEST2";
634 return func (a, ss, b);
637 return 1;
640 typedef int (STDCALL *OutVTypeDelegate) (int a, simplestruct *ss, int b);
642 LIBTEST_API int STDCALL
643 mono_test_marshal_out_struct (int a, simplestruct *ss, int b, OutVTypeDelegate func)
645 /* Check that the input pointer is ignored */
646 ss->d = (const char *)0x12345678;
648 func (a, ss, b);
650 if (ss->a && ss->b && ss->c && !strcmp (ss->d, "TEST3"))
651 return 0;
652 else
653 return 1;
656 typedef int (STDCALL *InVTypeDelegate) (int a, simplestruct *ss, int b);
658 LIBTEST_API int STDCALL
659 mono_test_marshal_in_struct (int a, simplestruct *ss, int b, InVTypeDelegate func)
661 simplestruct ss2;
662 int res;
664 memcpy (&ss2, ss, sizeof (simplestruct));
666 res = func (a, ss, b);
667 if (res) {
668 printf ("mono_test_marshal_in_struct () failed: %d\n", res);
669 return 1;
672 /* Check that no modifications is made to the struct */
673 if (ss2.a == ss->a && ss2.b == ss->b && ss2.c == ss->c && ss2.d == ss->d)
674 return 0;
675 else
676 return 1;
679 typedef struct {
680 int a;
681 SimpleDelegate func, func2, func3;
682 } DelegateStruct;
684 LIBTEST_API DelegateStruct STDCALL
685 mono_test_marshal_delegate_struct (DelegateStruct ds)
687 DelegateStruct res;
689 res.a = ds.func (ds.a) + ds.func2 (ds.a) + (ds.func3 == NULL ? 0 : 1);
690 res.func = ds.func;
691 res.func2 = ds.func2;
692 res.func3 = NULL;
694 return res;
697 LIBTEST_API int STDCALL
698 mono_test_marshal_struct (simplestruct ss)
700 if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
701 !strcmp (ss.d, "TEST"))
702 return 0;
704 return 1;
707 LIBTEST_API int STDCALL
708 mono_test_marshal_byref_struct (simplestruct *ss, int a, int b, int c, char *d)
710 gboolean res = (ss->a == a && ss->b == b && ss->c == c && strcmp (ss->d, d) == 0);
712 marshal_free ((char*)ss->d);
714 ss->a = !ss->a;
715 ss->b = !ss->b;
716 ss->c = !ss->c;
717 ss->d = marshal_strdup ("DEF");
719 return res ? 0 : 1;
722 typedef struct {
723 int a;
724 int b;
725 int c;
726 char *d;
727 unsigned char e;
728 double f;
729 unsigned char g;
730 guint64 h;
731 } simplestruct2;
733 LIBTEST_API int STDCALL
734 mono_test_marshal_struct2 (simplestruct2 ss)
736 if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
737 !strcmp (ss.d, "TEST") &&
738 ss.e == 99 && ss.f == 1.5 && ss.g == 42 && ss.h == (guint64)123)
739 return 0;
741 return 1;
744 /* on HP some of the struct should be on the stack and not in registers */
745 LIBTEST_API int STDCALL
746 mono_test_marshal_struct2_2 (int i, int j, int k, simplestruct2 ss)
748 if (i != 10 || j != 11 || k != 12)
749 return 1;
750 if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
751 !strcmp (ss.d, "TEST") &&
752 ss.e == 99 && ss.f == 1.5 && ss.g == 42 && ss.h == (guint64)123)
753 return 0;
755 return 1;
758 LIBTEST_API int STDCALL
759 mono_test_marshal_lpstruct (simplestruct *ss)
761 if (ss->a == 0 && ss->b == 1 && ss->c == 0 &&
762 !strcmp (ss->d, "TEST"))
763 return 0;
765 return 1;
768 LIBTEST_API int STDCALL
769 mono_test_marshal_lpstruct_blittable (point *p)
771 if (p->x == 1.0 && p->y == 2.0)
772 return 0;
773 else
774 return 1;
777 LIBTEST_API int STDCALL
778 mono_test_marshal_struct_array (simplestruct2 *ss)
780 if (! (ss[0].a == 0 && ss[0].b == 1 && ss[0].c == 0 &&
781 !strcmp (ss[0].d, "TEST") &&
782 ss[0].e == 99 && ss[0].f == 1.5 && ss[0].g == 42 && ss[0].h == (guint64)123))
783 return 1;
785 if (! (ss[1].a == 0 && ss[1].b == 0 && ss[1].c == 0 &&
786 !strcmp (ss[1].d, "TEST2") &&
787 ss[1].e == 100 && ss[1].f == 2.5 && ss[1].g == 43 && ss[1].h == (guint64)124))
788 return 1;
790 return 0;
793 typedef struct long_align_struct {
794 gint32 a;
795 gint64 b;
796 gint64 c;
797 } long_align_struct;
799 LIBTEST_API int STDCALL
800 mono_test_marshal_long_align_struct_array (long_align_struct *ss)
802 return ss[0].a + ss[0].b + ss[0].c + ss[1].a + ss[1].b + ss[1].c;
805 LIBTEST_API simplestruct2 * STDCALL
806 mono_test_marshal_class (int i, int j, int k, simplestruct2 *ss, int l)
808 simplestruct2 *res;
810 if (!ss)
811 return NULL;
813 if (i != 10 || j != 11 || k != 12 || l != 14)
814 return NULL;
815 if (! (ss->a == 0 && ss->b == 1 && ss->c == 0 &&
816 !strcmp (ss->d, "TEST") &&
817 ss->e == 99 && ss->f == 1.5 && ss->g == 42 && ss->h == (guint64)123))
818 return NULL;
820 res = marshal_new0 (simplestruct2, 1);
821 memcpy (res, ss, sizeof (simplestruct2));
822 res->d = marshal_strdup ("TEST");
823 return res;
826 LIBTEST_API int STDCALL
827 mono_test_marshal_byref_class (simplestruct2 **ssp)
829 simplestruct2 *ss = *ssp;
830 simplestruct2 *res;
832 if (! (ss->a == 0 && ss->b == 1 && ss->c == 0 &&
833 !strcmp (ss->d, "TEST") &&
834 ss->e == 99 && ss->f == 1.5 && ss->g == 42 && ss->h == (guint64)123))
835 return 1;
837 res = marshal_new0 (simplestruct2, 1);
838 memcpy (res, ss, sizeof (simplestruct2));
839 res->d = marshal_strdup ("TEST-RES");
841 *ssp = res;
842 return 0;
845 static void *
846 get_sp (void)
848 int i;
849 void *p;
851 /* Yes, this is correct, we are only trying to determine the value of the stack here */
852 p = &i;
853 return p;
856 LIBTEST_API int STDCALL
857 reliable_delegate (int a)
859 return a;
863 * Checks whether get_sp() works as expected. It doesn't work with gcc-2.95.3 on linux.
865 static gboolean
866 is_get_sp_reliable (void)
868 void *sp1, *sp2;
870 reliable_delegate(1);
871 sp1 = get_sp();
872 reliable_delegate(1);
873 sp2 = get_sp();
874 return sp1 == sp2;
877 LIBTEST_API int STDCALL
878 mono_test_marshal_delegate (SimpleDelegate delegate)
880 void *sp1, *sp2;
882 /* Check that the delegate wrapper is stdcall */
883 delegate (2);
884 sp1 = get_sp ();
885 delegate (2);
886 sp2 = get_sp ();
887 if (is_get_sp_reliable())
888 g_assert (sp1 == sp2);
890 return delegate (2);
893 static int STDCALL inc_cb (int i)
895 return i + 1;
898 LIBTEST_API int STDCALL
899 mono_test_marshal_out_delegate (SimpleDelegate *delegate)
901 *delegate = inc_cb;
903 return 0;
906 LIBTEST_API SimpleDelegate STDCALL
907 mono_test_marshal_return_delegate (SimpleDelegate delegate)
909 return delegate;
912 typedef int (STDCALL *DelegateByrefDelegate) (void *);
914 LIBTEST_API int STDCALL
915 mono_test_marshal_delegate_ref_delegate (DelegateByrefDelegate del)
917 int (STDCALL *ptr) (int i);
919 del (&ptr);
921 return ptr (54);
924 static int STDCALL
925 return_plus_one (int i)
927 return i + 1;
930 LIBTEST_API SimpleDelegate STDCALL
931 mono_test_marshal_return_delegate_2 (void)
933 return return_plus_one;
936 typedef simplestruct (STDCALL *SimpleDelegate2) (simplestruct ss);
938 static gboolean
939 is_utf16_equals (gunichar2 *s1, const char *s2)
941 char *s;
942 int res;
944 s = g_utf16_to_utf8 (s1, -1, NULL, NULL, NULL);
945 res = strcmp (s, s2);
946 g_free (s);
948 return res == 0;
951 LIBTEST_API int STDCALL
952 mono_test_marshal_delegate2 (SimpleDelegate2 delegate)
954 simplestruct ss, res;
956 ss.a = 0;
957 ss.b = 1;
958 ss.c = 0;
959 ss.d = "TEST";
960 ss.d2 = g_utf8_to_utf16 ("TEST2", -1, NULL, NULL, NULL);
962 res = delegate (ss);
963 if (! (res.a && !res.b && res.c && !strcmp (res.d, "TEST-RES") && is_utf16_equals (res.d2, "TEST2-RES")))
964 return 1;
966 return 0;
969 typedef simplestruct* (STDCALL *SimpleDelegate4) (simplestruct *ss);
971 LIBTEST_API int STDCALL
972 mono_test_marshal_delegate4 (SimpleDelegate4 delegate)
974 simplestruct ss;
975 simplestruct *res;
977 ss.a = 0;
978 ss.b = 1;
979 ss.c = 0;
980 ss.d = "TEST";
982 /* Check argument */
983 res = delegate (&ss);
984 if (!res)
985 return 1;
987 /* Check return value */
988 if (! (!res->a && res->b && !res->c && !strcmp (res->d, "TEST")))
989 return 2;
991 /* Check NULL argument and NULL result */
992 res = delegate (NULL);
993 if (res)
994 return 3;
996 return 0;
999 typedef int (STDCALL *SimpleDelegate5) (simplestruct **ss);
1001 LIBTEST_API int STDCALL
1002 mono_test_marshal_delegate5 (SimpleDelegate5 delegate)
1004 simplestruct ss;
1005 int res;
1006 simplestruct *ptr;
1008 ss.a = 0;
1009 ss.b = 1;
1010 ss.c = 0;
1011 ss.d = "TEST";
1013 ptr = &ss;
1015 res = delegate (&ptr);
1016 if (res != 0)
1017 return 1;
1019 if (!(ptr->a && !ptr->b && ptr->c && !strcmp (ptr->d, "RES")))
1020 return 2;
1022 return 0;
1025 LIBTEST_API int STDCALL
1026 mono_test_marshal_delegate6 (SimpleDelegate5 delegate)
1028 delegate (NULL);
1029 return 0;
1032 typedef int (STDCALL *SimpleDelegate7) (simplestruct **ss);
1034 LIBTEST_API int STDCALL
1035 mono_test_marshal_delegate7 (SimpleDelegate7 delegate)
1037 int res;
1038 simplestruct *ptr;
1040 /* Check that the input pointer is ignored */
1041 ptr = (simplestruct *)0x12345678;
1043 res = delegate (&ptr);
1044 if (res != 0)
1045 return 1;
1047 if (!(ptr->a && !ptr->b && ptr->c && !strcmp (ptr->d, "RES")))
1048 return 2;
1050 return 0;
1053 typedef int (STDCALL *InOutByvalClassDelegate) (simplestruct *ss);
1055 LIBTEST_API int STDCALL
1056 mono_test_marshal_inout_byval_class_delegate (InOutByvalClassDelegate delegate)
1058 int res;
1059 simplestruct ss;
1061 ss.a = FALSE;
1062 ss.b = TRUE;
1063 ss.c = FALSE;
1064 ss.d = g_strdup_printf ("%s", "FOO");
1066 res = delegate (&ss);
1067 if (res != 0)
1068 return 1;
1070 if (!(ss.a && !ss.b && ss.c && !strcmp (ss.d, "RES")))
1071 return 2;
1073 return 0;
1076 typedef int (STDCALL *SimpleDelegate8) (gunichar2 *s);
1078 LIBTEST_API int STDCALL
1079 mono_test_marshal_delegate8 (SimpleDelegate8 delegate, gunichar2 *s)
1081 return delegate (s);
1084 typedef int (STDCALL *return_int_fnt) (int i);
1085 typedef int (STDCALL *SimpleDelegate9) (return_int_fnt d);
1087 LIBTEST_API int STDCALL
1088 mono_test_marshal_delegate9 (SimpleDelegate9 delegate, gpointer ftn)
1090 return delegate ((return_int_fnt)ftn);
1093 static int STDCALL
1094 return_self (int i)
1096 return i;
1099 LIBTEST_API int STDCALL
1100 mono_test_marshal_delegate10 (SimpleDelegate9 delegate)
1102 return delegate (return_self);
1105 typedef int (STDCALL *PrimitiveByrefDelegate) (int *i);
1107 LIBTEST_API int STDCALL
1108 mono_test_marshal_primitive_byref_delegate (PrimitiveByrefDelegate delegate)
1110 int i = 1;
1112 int res = delegate (&i);
1113 if (res != 0)
1114 return res;
1116 if (i != 2)
1117 return 2;
1119 return 0;
1122 typedef int (STDCALL *return_int_delegate) (int i);
1124 typedef return_int_delegate (STDCALL *ReturnDelegateDelegate) (void);
1126 LIBTEST_API int STDCALL
1127 mono_test_marshal_return_delegate_delegate (ReturnDelegateDelegate d)
1129 return (d ()) (55);
1132 typedef int (STDCALL *VirtualDelegate) (int);
1134 LIBTEST_API int STDCALL
1135 mono_test_marshal_virtual_delegate (VirtualDelegate del)
1137 return del (42);
1140 typedef char* (STDCALL *IcallDelegate) (const char *);
1141 LIBTEST_API int STDCALL
1142 mono_test_marshal_icall_delegate (IcallDelegate del)
1144 char *res = del ("ABC");
1145 return strcmp (res, "ABC") == 0 ? 0 : 1;
1148 LIBTEST_API int STDCALL
1149 mono_test_marshal_stringbuilder (char *s, int n)
1151 const char m[] = "This is my message. Isn't it nice?";
1153 if (strcmp (s, "ABCD") != 0)
1154 return 1;
1155 memcpy(s, m, n);
1156 s [n] = '\0';
1157 return 0;
1160 LIBTEST_API int STDCALL
1161 mono_test_marshal_stringbuilder_append (char *s, int length)
1163 const char out_sentinel[] = "CSHARP_";
1164 const char out_len = strlen (out_sentinel);
1166 for (int i=0; i < length; i++) {
1167 s [i] = out_sentinel [i % out_len];
1170 s [length] = '\0';
1173 return 0;
1176 LIBTEST_API int STDCALL
1177 mono_test_marshal_stringbuilder_default (char *s, int n)
1179 const char m[] = "This is my message. Isn't it nice?";
1181 memcpy(s, m, n);
1182 s [n] = '\0';
1183 return 0;
1186 LIBTEST_API int STDCALL
1187 mono_test_marshal_stringbuilder_unicode (gunichar2 *s, int n)
1189 const char m[] = "This is my message. Isn't it nice?";
1190 gunichar2* s2;
1191 glong len;
1193 s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
1195 len = (len * 2) + 2;
1196 if (len > (n * 2))
1197 len = n * 2;
1198 memcpy (s, s2, len);
1200 g_free (s2);
1202 return 0;
1205 LIBTEST_API void STDCALL
1206 mono_test_marshal_stringbuilder_out (char **s)
1208 const char m[] = "This is my message. Isn't it nice?";
1209 char *str;
1211 str = (char *)marshal_alloc (strlen (m) + 1);
1212 memcpy (str, m, strlen (m) + 1);
1214 *s = str;
1217 LIBTEST_API int STDCALL
1218 mono_test_marshal_stringbuilder_out_unicode (gunichar2 **s)
1220 const char m[] = "This is my message. Isn't it nice?";
1221 gunichar2 *s2;
1222 glong len;
1224 s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
1226 len = (len * 2) + 2;
1227 *s = (gunichar2 *)marshal_alloc (len);
1228 memcpy (*s, s2, len);
1230 g_free (s2);
1232 return 0;
1235 LIBTEST_API int STDCALL
1236 mono_test_marshal_stringbuilder_ref (char **s)
1238 const char m[] = "This is my message. Isn't it nice?";
1239 char *str;
1241 if (strcmp (*s, "ABC"))
1242 return 1;
1244 str = (char *)marshal_alloc (strlen (m) + 1);
1245 memcpy (str, m, strlen (m) + 1);
1247 *s = str;
1248 return 0;
1251 #ifdef __GNUC__
1252 #pragma GCC diagnostic push
1253 #pragma GCC diagnostic ignored "-Wc++-compat"
1254 #endif
1257 * Standard C and C++ doesn't allow empty structs, empty structs will always have a size of 1 byte.
1258 * GCC have an extension to allow empty structs, https://gcc.gnu.org/onlinedocs/gcc/Empty-Structures.html.
1259 * This cause a little dilemma since runtime build using none GCC compiler will not be compatible with
1260 * GCC build C libraries and the other way around. On platforms where empty structs has size of 1 byte
1261 * it must be represented in call and cannot be dropped. On Windows x64 structs will always be represented in the call
1262 * meaning that an empty struct must have a representation in the callee in order to correctly follow the ABI used by the
1263 * C/C++ standard and the runtime.
1265 typedef struct {
1266 #if !defined(__GNUC__) || defined(TARGET_WIN32)
1267 char a;
1268 #endif
1269 } EmptyStruct;
1271 #ifdef __GNUC__
1272 #pragma GCC diagnostic pop
1273 #endif
1275 LIBTEST_API int STDCALL
1276 mono_test_marshal_empty_string_array (char **array)
1278 return (array == NULL) ? 0 : 1;
1281 LIBTEST_API int STDCALL
1282 mono_test_marshal_string_array (char **array)
1284 if (strcmp (array [0], "ABC"))
1285 return 1;
1286 if (strcmp (array [1], "DEF"))
1287 return 2;
1289 if (array [2] != NULL)
1290 return 3;
1292 return 0;
1295 LIBTEST_API int STDCALL
1296 mono_test_marshal_byref_string_array (char ***array)
1298 if (*array == NULL)
1299 return 0;
1301 if (strcmp ((*array) [0], "Alpha"))
1302 return 2;
1303 if (strcmp ((*array) [1], "Beta"))
1304 return 2;
1305 if (strcmp ((*array) [2], "Gamma"))
1306 return 2;
1308 return 1;
1311 LIBTEST_API int STDCALL
1312 mono_test_marshal_stringbuilder_array (char **array)
1314 if (strcmp (array [0], "ABC"))
1315 return 1;
1316 if (strcmp (array [1], "DEF"))
1317 return 2;
1319 strcpy (array [0], "DEF");
1320 strcpy (array [1], "ABC");
1322 return 0;
1325 LIBTEST_API int STDCALL
1326 mono_test_marshal_unicode_string_array (gunichar2 **array, char **array2)
1328 GError *gerror = NULL;
1329 char *s;
1331 s = g_utf16_to_utf8 (array [0], -1, NULL, NULL, &gerror);
1332 if (strcmp (s, "ABC")) {
1333 g_free (s);
1334 return 1;
1336 else
1337 g_free (s);
1339 s = g_utf16_to_utf8 (array [1], -1, NULL, NULL, &gerror);
1340 if (strcmp (s, "DEF")) {
1341 g_free (s);
1342 return 2;
1344 else
1345 g_free (s);
1347 if (strcmp (array2 [0], "ABC"))
1348 return 3;
1350 if (strcmp (array2 [1], "DEF"))
1351 return 4;
1353 return 0;
1356 /* this does not work on Redhat gcc 2.96 */
1357 LIBTEST_API int STDCALL
1358 mono_test_empty_struct (int a, EmptyStruct es, int b)
1360 // printf ("mono_test_empty_struct %d %d\n", a, b);
1362 // Intel icc on ia64 passes 'es' in 2 registers
1363 #if defined(__ia64) && defined(__INTEL_COMPILER)
1364 return 0;
1365 #else
1366 if (a == 1 && b == 2)
1367 return 0;
1368 return 1;
1369 #endif
1372 LIBTEST_API EmptyStruct STDCALL
1373 mono_test_return_empty_struct (int a)
1375 EmptyStruct s;
1377 memset (&s, 0, sizeof (s));
1379 #if !(defined(__i386__) && defined(__clang__))
1380 /* https://bugzilla.xamarin.com/show_bug.cgi?id=58901 */
1381 g_assert (a == 42);
1382 #endif
1384 return s;
1387 typedef struct {
1388 char a[100];
1389 } ByValStrStruct;
1391 LIBTEST_API ByValStrStruct * STDCALL
1392 mono_test_byvalstr_gen (void)
1394 ByValStrStruct *ret;
1396 ret = (ByValStrStruct *)malloc (sizeof (ByValStrStruct));
1397 memset(ret, 'a', sizeof(ByValStrStruct)-1);
1398 ret->a[sizeof(ByValStrStruct)-1] = 0;
1400 return ret;
1403 LIBTEST_API int STDCALL
1404 mono_test_byvalstr_check (ByValStrStruct* data, char* correctString)
1406 int ret;
1408 ret = strcmp(data->a, correctString);
1409 // printf ("T1: %s\n", data->a);
1410 // printf ("T2: %s\n", correctString);
1412 /* we need g_free because the allocation was performed by mono_test_byvalstr_gen */
1413 g_free (data);
1414 return (ret != 0);
1417 typedef struct {
1418 guint16 a[4];
1419 int flag;
1420 } ByValStrStruct_Unicode;
1422 LIBTEST_API int STDCALL
1423 mono_test_byvalstr_check_unicode (ByValStrStruct_Unicode *ref, int test)
1425 if (ref->flag != 0x1234abcd){
1426 printf ("overwritten data");
1427 return 1;
1430 if (test == 1 || test == 3){
1431 if (ref->a [0] != '1' ||
1432 ref->a [1] != '2' ||
1433 ref->a [2] != '3')
1434 return 1;
1435 return 0;
1437 if (test == 2){
1438 if (ref->a [0] != '1' ||
1439 ref->a [1] != '2')
1440 return 1;
1441 return 0;
1443 return 10;
1446 LIBTEST_API int STDCALL
1447 NameManglingAnsi (char *data)
1449 return data [0] + data [1] + data [2];
1452 LIBTEST_API int STDCALL
1453 NameManglingAnsiA (char *data)
1455 g_assert_not_reached ();
1458 LIBTEST_API int STDCALL
1459 NameManglingAnsiW (char *data)
1461 g_assert_not_reached ();
1464 LIBTEST_API int STDCALL
1465 NameManglingAnsi2A (char *data)
1467 return data [0] + data [1] + data [2];
1470 LIBTEST_API int STDCALL
1471 NameManglingAnsi2W (char *data)
1473 g_assert_not_reached ();
1476 LIBTEST_API int STDCALL
1477 NameManglingUnicode (char *data)
1479 g_assert_not_reached ();
1482 LIBTEST_API int STDCALL
1483 NameManglingUnicodeW (gunichar2 *data)
1485 return data [0] + data [1] + data [2];
1488 LIBTEST_API int STDCALL
1489 NameManglingUnicode2 (gunichar2 *data)
1491 return data [0] + data [1] + data [2];
1494 LIBTEST_API int STDCALL
1495 NameManglingAutoW (char *data)
1497 #ifdef WIN32
1498 return (data [0] + data [1] + data [2]) == 131 ? 0 : 1;
1499 #else
1500 g_assert_not_reached ();
1501 #endif
1504 LIBTEST_API int STDCALL
1505 NameManglingAuto (char *data)
1507 #ifndef WIN32
1508 return (data [0] + data [1] + data [2]) == 198 ? 0 : 1;
1509 #else
1510 g_assert_not_reached ();
1511 #endif
1514 typedef int (STDCALL *intcharFunc)(const char*);
1516 LIBTEST_API void STDCALL
1517 callFunction (intcharFunc f)
1519 f ("ABC");
1522 typedef struct {
1523 const char* str;
1524 int i;
1525 } SimpleObj;
1527 LIBTEST_API int STDCALL
1528 class_marshal_test0 (SimpleObj *obj1)
1530 // printf ("class_marshal_test0 %s %d\n", obj1->str, obj1->i);
1532 if (strcmp(obj1->str, "T1"))
1533 return -1;
1534 if (obj1->i != 4)
1535 return -2;
1537 return 0;
1540 LIBTEST_API int STDCALL
1541 class_marshal_test4 (SimpleObj *obj1)
1543 if (obj1)
1544 return -1;
1546 return 0;
1549 LIBTEST_API void STDCALL
1550 class_marshal_test1 (SimpleObj **obj1)
1552 SimpleObj *res = (SimpleObj *)malloc (sizeof (SimpleObj));
1554 res->str = marshal_strdup ("ABC");
1555 res->i = 5;
1557 *obj1 = res;
1560 LIBTEST_API int STDCALL
1561 class_marshal_test2 (SimpleObj **obj1)
1563 // printf ("class_marshal_test2 %s %d\n", (*obj1)->str, (*obj1)->i);
1565 if (strcmp((*obj1)->str, "ABC"))
1566 return -1;
1567 if ((*obj1)->i != 5)
1568 return -2;
1570 return 0;
1573 LIBTEST_API int STDCALL
1574 string_marshal_test0 (char *str)
1576 if (strcmp (str, "TEST0"))
1577 return -1;
1579 return 0;
1582 LIBTEST_API void STDCALL
1583 string_marshal_test1 (const char **str)
1585 *str = marshal_strdup ("TEST1");
1588 LIBTEST_API int STDCALL
1589 string_marshal_test2 (char **str)
1591 // printf ("string_marshal_test2 %s\n", *str);
1593 if (strcmp (*str, "TEST1"))
1594 return -1;
1596 *str = marshal_strdup ("TEST2");
1598 return 0;
1601 LIBTEST_API int STDCALL
1602 string_marshal_test3 (char *str)
1604 if (str)
1605 return -1;
1607 return 0;
1610 typedef struct {
1611 int a;
1612 int b;
1613 } BlittableClass;
1615 LIBTEST_API BlittableClass* STDCALL
1616 TestBlittableClass (BlittableClass *vl)
1618 BlittableClass *res;
1620 // printf ("TestBlittableClass %d %d\n", vl->a, vl->b);
1622 if (vl) {
1623 vl->a++;
1624 vl->b++;
1626 res = marshal_new0 (BlittableClass, 1);
1627 memcpy (res, vl, sizeof (BlittableClass));
1628 } else {
1629 res = marshal_new0 (BlittableClass, 1);
1630 res->a = 42;
1631 res->b = 43;
1634 return res;
1637 typedef struct OSVERSIONINFO_STRUCT
1639 int a;
1640 int b;
1641 } OSVERSIONINFO_STRUCT;
1643 LIBTEST_API int STDCALL
1644 MyGetVersionEx (OSVERSIONINFO_STRUCT *osvi)
1647 // printf ("GOT %d %d\n", osvi->a, osvi->b);
1649 osvi->a += 1;
1650 osvi->b += 1;
1652 return osvi->a + osvi->b;
1655 LIBTEST_API int STDCALL
1656 BugGetVersionEx (int a, int b, int c, int d, int e, int f, int g, int h, OSVERSIONINFO_STRUCT *osvi)
1659 // printf ("GOT %d %d\n", osvi->a, osvi->b);
1661 osvi->a += 1;
1662 osvi->b += 1;
1664 return osvi->a + osvi->b;
1667 LIBTEST_API int STDCALL
1668 mono_test_marshal_point (point pt)
1670 // printf("point %g %g\n", pt.x, pt.y);
1671 if (pt.x == 1.25 && pt.y == 3.5)
1672 return 0;
1674 return 1;
1677 typedef struct {
1678 int x;
1679 double y;
1680 } mixed_point;
1682 LIBTEST_API int STDCALL
1683 mono_test_marshal_mixed_point (mixed_point pt)
1685 // printf("mixed point %d %g\n", pt.x, pt.y);
1686 if (pt.x == 5 && pt.y == 6.75)
1687 return 0;
1689 return 1;
1692 LIBTEST_API int STDCALL
1693 mono_test_marshal_mixed_point_2 (mixed_point *pt)
1695 if (pt->x != 5 || pt->y != 6.75)
1696 return 1;
1698 pt->x = 10;
1699 pt->y = 12.35;
1701 return 0;
1704 LIBTEST_API int STDCALL
1705 marshal_test_ref_bool(int i, char *b1, short *b2, int *b3)
1707 int res = 1;
1708 if (*b1 != 0 && *b1 != 1)
1709 return 1;
1710 if (*b2 != 0 && *b2 != -1) /* variant_bool */
1711 return 1;
1712 if (*b3 != 0 && *b3 != 1)
1713 return 1;
1714 if (i == ((*b1 << 2) | (-*b2 << 1) | *b3))
1715 res = 0;
1716 *b1 = !*b1;
1717 *b2 = ~*b2;
1718 *b3 = !*b3;
1719 return res;
1722 struct BoolStruct
1724 int i;
1725 char b1;
1726 short b2; /* variant_bool */
1727 int b3;
1730 LIBTEST_API int STDCALL
1731 marshal_test_bool_struct(struct BoolStruct *s)
1733 int res = 1;
1734 if (s->b1 != 0 && s->b1 != 1)
1735 return 1;
1736 if (s->b2 != 0 && s->b2 != -1)
1737 return 1;
1738 if (s->b3 != 0 && s->b3 != 1)
1739 return 1;
1740 if (s->i == ((s->b1 << 2) | (-s->b2 << 1) | s->b3))
1741 res = 0;
1742 s->b1 = !s->b1;
1743 s->b2 = ~s->b2;
1744 s->b3 = !s->b3;
1745 return res;
1748 typedef struct {
1749 gint64 l;
1750 } LongStruct2;
1752 typedef struct {
1753 int i;
1754 LongStruct2 l;
1755 } LongStruct;
1757 LIBTEST_API int STDCALL
1758 mono_test_marshal_long_struct (LongStruct *s)
1760 return s->i + s->l.l;
1763 LIBTEST_API void STDCALL
1764 mono_test_last_error (int err)
1766 #ifdef WIN32
1767 SetLastError (err);
1768 #else
1769 errno = err;
1770 #endif
1773 LIBTEST_API int STDCALL
1774 mono_test_asany (void *ptr, int what)
1776 switch (what) {
1777 case 1:
1778 return (*(int*)ptr == 5) ? 0 : 1;
1779 case 2:
1780 return strcmp (ptr, "ABC") == 0 ? 0 : 1;
1781 case 3: {
1782 simplestruct2 ss = *(simplestruct2*)ptr;
1784 if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
1785 !strcmp (ss.d, "TEST") &&
1786 ss.e == 99 && ss.f == 1.5 && ss.g == 42 && ss.h == (guint64)123)
1787 return 0;
1788 else
1789 return 1;
1791 case 4: {
1792 GError *gerror = NULL;
1793 char *s;
1795 s = g_utf16_to_utf8 ((const gunichar2 *)ptr, -1, NULL, NULL, &gerror);
1797 if (!s)
1798 return 1;
1800 if (!strcmp (s, "ABC")) {
1801 g_free (s);
1802 return 0;
1804 else {
1805 g_free (s);
1806 return 1;
1809 default:
1810 g_assert_not_reached ();
1813 return 1;
1816 typedef struct
1818 int i;
1819 int j;
1820 int k;
1821 char *s;
1822 } AsAnyStruct;
1824 LIBTEST_API int STDCALL
1825 mono_test_marshal_asany_in (void* ptr)
1827 AsAnyStruct *asAny = (AsAnyStruct *)ptr;
1828 int res = asAny->i + asAny->j + asAny->k;
1830 return res;
1833 LIBTEST_API int STDCALL
1834 mono_test_marshal_asany_inout (void* ptr)
1836 AsAnyStruct *asAny = (AsAnyStruct *)ptr;
1837 int res = asAny->i + asAny->j + asAny->k;
1839 marshal_free (asAny->s);
1841 asAny->i = 10;
1842 asAny->j = 20;
1843 asAny->k = 30;
1844 asAny->s = 0;
1846 return res;
1849 LIBTEST_API int STDCALL
1850 mono_test_marshal_asany_out (void* ptr)
1852 AsAnyStruct *asAny = (AsAnyStruct *)ptr;
1853 int res = asAny->i + asAny->j + asAny->k;
1855 asAny->i = 10;
1856 asAny->j = 20;
1857 asAny->k = 30;
1858 asAny->s = 0;
1860 return res;
1864 * AMD64 marshalling tests.
1867 typedef struct amd64_struct1 {
1868 int i;
1869 int j;
1870 int k;
1871 int l;
1872 } amd64_struct1;
1874 LIBTEST_API amd64_struct1 STDCALL
1875 mono_test_marshal_amd64_pass_return_struct1 (amd64_struct1 s)
1877 s.i ++;
1878 s.j ++;
1879 s.k ++;
1880 s.l ++;
1882 return s;
1885 LIBTEST_API amd64_struct1 STDCALL
1886 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)
1888 s.i ++;
1889 s.j ++;
1890 s.k ++;
1891 s.l += 1 + i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8;
1893 return s;
1896 typedef struct amd64_struct2 {
1897 int i;
1898 int j;
1899 } amd64_struct2;
1901 LIBTEST_API amd64_struct2 STDCALL
1902 mono_test_marshal_amd64_pass_return_struct2 (amd64_struct2 s)
1904 s.i ++;
1905 s.j ++;
1907 return s;
1910 typedef struct amd64_struct3 {
1911 int i;
1912 } amd64_struct3;
1914 LIBTEST_API amd64_struct3 STDCALL
1915 mono_test_marshal_amd64_pass_return_struct3 (amd64_struct3 s)
1917 s.i ++;
1919 return s;
1922 typedef struct amd64_struct4 {
1923 double d1, d2;
1924 } amd64_struct4;
1926 LIBTEST_API amd64_struct4 STDCALL
1927 mono_test_marshal_amd64_pass_return_struct4 (amd64_struct4 s)
1929 s.d1 ++;
1930 s.d2 ++;
1932 return s;
1936 * IA64 marshalling tests.
1938 typedef struct test_struct5 {
1939 float d1, d2;
1940 } test_struct5;
1942 LIBTEST_API test_struct5 STDCALL
1943 mono_test_marshal_ia64_pass_return_struct5 (double d1, double d2, test_struct5 s, int i, double d3, double d4)
1945 s.d1 += d1 + d2 + i;
1946 s.d2 += d3 + d4 + i;
1948 return s;
1951 typedef struct test_struct6 {
1952 double d1, d2;
1953 } test_struct6;
1955 LIBTEST_API test_struct6 STDCALL
1956 mono_test_marshal_ia64_pass_return_struct6 (double d1, double d2, test_struct6 s, int i, double d3, double d4)
1958 s.d1 += d1 + d2 + i;
1959 s.d2 += d3 + d4;
1961 return s;
1964 static guint32 custom_res [2];
1966 LIBTEST_API void* STDCALL
1967 mono_test_marshal_pass_return_custom (int i, guint32 *ptr, int j)
1969 /* ptr will be freed by CleanupNative, so make a copy */
1970 custom_res [0] = 0; /* not allocated by AllocHGlobal */
1971 custom_res [1] = ptr [1];
1973 return &custom_res;
1976 LIBTEST_API int STDCALL
1977 mono_test_marshal_pass_out_custom (int i, guint32 **ptr, int j)
1979 custom_res [0] = 0;
1980 custom_res [1] = i + j + 10;
1982 *ptr = custom_res;
1984 return 0;
1987 LIBTEST_API int STDCALL
1988 mono_test_marshal_pass_inout_custom (int i, guint32 *ptr, int j)
1990 ptr [0] = 0;
1991 ptr [1] = i + ptr [1] + j;
1993 return 0;
1996 LIBTEST_API int STDCALL
1997 mono_test_marshal_pass_out_byval_custom (int i, guint32 *ptr, int j)
1999 return ptr == NULL ? 0 : 1;
2002 LIBTEST_API int STDCALL
2003 mono_test_marshal_pass_byref_custom (int i, guint32 **ptr, int j)
2005 (*ptr)[1] += i + j;
2007 return 0;
2010 LIBTEST_API void* STDCALL
2011 mono_test_marshal_pass_return_custom2 (int i, guint32 *ptr, int j)
2013 g_assert_not_reached ();
2015 return NULL;
2018 LIBTEST_API void* STDCALL
2019 mono_test_marshal_pass_return_custom_null (int i, guint32 *ptr, int j)
2021 g_assert (ptr == NULL);
2023 return NULL;
2026 typedef void *(STDCALL *PassReturnPtrDelegate) (void *ptr);
2028 LIBTEST_API int STDCALL
2029 mono_test_marshal_pass_return_custom_in_delegate (PassReturnPtrDelegate del)
2031 guint32 buf [2];
2032 guint32 res;
2033 guint32 *ptr;
2035 buf [0] = 0;
2036 buf [1] = 10;
2038 ptr = (guint32 *)del (&buf);
2040 res = ptr [1];
2042 #ifdef WIN32
2043 /* FIXME: Freed with FreeHGlobal */
2044 #else
2045 g_free (ptr);
2046 #endif
2048 return res;
2051 LIBTEST_API int STDCALL
2052 mono_test_marshal_pass_return_custom_null_in_delegate (PassReturnPtrDelegate del)
2054 void *ptr = del (NULL);
2056 return (ptr == NULL) ? 15 : 0;
2059 typedef void (STDCALL *CustomOutParamDelegate) (void **pptr);
2061 LIBTEST_API int STDCALL
2062 mono_test_marshal_custom_out_param_delegate (CustomOutParamDelegate del)
2064 void* pptr = del;
2066 del (&pptr);
2068 if(pptr != NULL)
2069 return 1;
2071 return 0;
2074 typedef int (STDCALL *ReturnEnumDelegate) (int e);
2076 LIBTEST_API int STDCALL
2077 mono_test_marshal_return_enum_delegate (ReturnEnumDelegate func)
2079 return func (1);
2082 typedef struct {
2083 int a, b, c;
2084 gint64 d;
2085 } BlittableStruct;
2087 typedef BlittableStruct (STDCALL *SimpleDelegate10) (BlittableStruct ss);
2089 LIBTEST_API int STDCALL
2090 mono_test_marshal_blittable_struct_delegate (SimpleDelegate10 delegate)
2092 BlittableStruct ss, res;
2094 ss.a = 1;
2095 ss.b = 2;
2096 ss.c = 3;
2097 ss.d = 55;
2099 res = delegate (ss);
2100 if (! ((res.a == -1) && (res.b == -2) && (res.c == -3) && (res.d == -55)))
2101 return 1;
2103 return 0;
2106 LIBTEST_API int STDCALL
2107 mono_test_stdcall_name_mangling (int a, int b, int c)
2109 return a + b + c;
2112 LIBTEST_API int
2113 mono_test_stdcall_mismatch_1 (int a, int b, int c)
2115 return a + b + c;
2118 LIBTEST_API int STDCALL
2119 mono_test_stdcall_mismatch_2 (int a, int b, int c)
2121 return a + b + c;
2125 * PASSING AND RETURNING SMALL STRUCTURES FROM DELEGATES TESTS
2128 typedef struct {
2129 int i;
2130 } SmallStruct1;
2132 typedef SmallStruct1 (STDCALL *SmallStructDelegate1) (SmallStruct1 ss);
2134 LIBTEST_API int STDCALL
2135 mono_test_marshal_small_struct_delegate1 (SmallStructDelegate1 delegate)
2137 SmallStruct1 ss, res;
2139 ss.i = 1;
2141 res = delegate (ss);
2142 if (! (res.i == -1))
2143 return 1;
2145 return 0;
2148 typedef struct {
2149 gint16 i, j;
2150 } SmallStruct2;
2152 typedef SmallStruct2 (STDCALL *SmallStructDelegate2) (SmallStruct2 ss);
2154 LIBTEST_API int STDCALL
2155 mono_test_marshal_small_struct_delegate2 (SmallStructDelegate2 delegate)
2157 SmallStruct2 ss, res;
2159 ss.i = 2;
2160 ss.j = 3;
2162 res = delegate (ss);
2163 if (! ((res.i == -2) && (res.j == -3)))
2164 return 1;
2166 return 0;
2169 typedef struct {
2170 gint16 i;
2171 gint8 j;
2172 } SmallStruct3;
2174 typedef SmallStruct3 (STDCALL *SmallStructDelegate3) (SmallStruct3 ss);
2176 LIBTEST_API int STDCALL
2177 mono_test_marshal_small_struct_delegate3 (SmallStructDelegate3 delegate)
2179 SmallStruct3 ss, res;
2181 ss.i = 1;
2182 ss.j = 2;
2184 res = delegate (ss);
2185 if (! ((res.i == -1) && (res.j == -2)))
2186 return 1;
2188 return 0;
2191 typedef struct {
2192 gint16 i;
2193 } SmallStruct4;
2195 typedef SmallStruct4 (STDCALL *SmallStructDelegate4) (SmallStruct4 ss);
2197 LIBTEST_API int STDCALL
2198 mono_test_marshal_small_struct_delegate4 (SmallStructDelegate4 delegate)
2200 SmallStruct4 ss, res;
2202 ss.i = 1;
2204 res = delegate (ss);
2205 if (! (res.i == -1))
2206 return 1;
2208 return 0;
2211 typedef struct {
2212 gint64 i;
2213 } SmallStruct5;
2215 typedef SmallStruct5 (STDCALL *SmallStructDelegate5) (SmallStruct5 ss);
2217 LIBTEST_API int STDCALL
2218 mono_test_marshal_small_struct_delegate5 (SmallStructDelegate5 delegate)
2220 SmallStruct5 ss, res;
2222 ss.i = 5;
2224 res = delegate (ss);
2225 if (! (res.i == -5))
2226 return 1;
2228 return 0;
2231 typedef struct {
2232 int i, j;
2233 } SmallStruct6;
2235 typedef SmallStruct6 (STDCALL *SmallStructDelegate6) (SmallStruct6 ss);
2237 LIBTEST_API int STDCALL
2238 mono_test_marshal_small_struct_delegate6 (SmallStructDelegate6 delegate)
2240 SmallStruct6 ss, res;
2242 ss.i = 1;
2243 ss.j = 2;
2245 res = delegate (ss);
2246 if (! ((res.i == -1) && (res.j == -2)))
2247 return 1;
2249 return 0;
2252 typedef struct {
2253 int i;
2254 gint16 j;
2255 } SmallStruct7;
2257 typedef SmallStruct7 (STDCALL *SmallStructDelegate7) (SmallStruct7 ss);
2259 LIBTEST_API int STDCALL
2260 mono_test_marshal_small_struct_delegate7 (SmallStructDelegate7 delegate)
2262 SmallStruct7 ss, res;
2264 ss.i = 1;
2265 ss.j = 2;
2267 res = delegate (ss);
2268 if (! ((res.i == -1) && (res.j == -2)))
2269 return 1;
2271 return 0;
2274 typedef struct {
2275 float i;
2276 } SmallStruct8;
2278 typedef SmallStruct8 (STDCALL *SmallStructDelegate8) (SmallStruct8 ss);
2280 LIBTEST_API int STDCALL
2281 mono_test_marshal_small_struct_delegate8 (SmallStructDelegate8 delegate)
2283 SmallStruct8 ss, res;
2285 ss.i = 1.0;
2287 res = delegate (ss);
2288 if (! ((res.i == -1.0)))
2289 return 1;
2291 return 0;
2294 typedef struct {
2295 double i;
2296 } SmallStruct9;
2298 typedef SmallStruct9 (STDCALL *SmallStructDelegate9) (SmallStruct9 ss);
2300 LIBTEST_API int STDCALL
2301 mono_test_marshal_small_struct_delegate9 (SmallStructDelegate9 delegate)
2303 SmallStruct9 ss, res;
2305 ss.i = 1.0;
2307 res = delegate (ss);
2308 if (! ((res.i == -1.0)))
2309 return 1;
2311 return 0;
2314 typedef struct {
2315 float i, j;
2316 } SmallStruct10;
2318 typedef SmallStruct10 (STDCALL *SmallStructDelegate10) (SmallStruct10 ss);
2320 LIBTEST_API int STDCALL
2321 mono_test_marshal_small_struct_delegate10 (SmallStructDelegate10 delegate)
2323 SmallStruct10 ss, res;
2325 ss.i = 1.0;
2326 ss.j = 2.0;
2328 res = delegate (ss);
2329 if (! ((res.i == -1.0) && (res.j == -2.0)))
2330 return 1;
2332 return 0;
2335 typedef struct {
2336 float i;
2337 int j;
2338 } SmallStruct11;
2340 typedef SmallStruct11 (STDCALL *SmallStructDelegate11) (SmallStruct11 ss);
2342 LIBTEST_API int STDCALL
2343 mono_test_marshal_small_struct_delegate11 (SmallStructDelegate11 delegate)
2345 SmallStruct11 ss, res;
2347 ss.i = 1.0;
2348 ss.j = 2;
2350 res = delegate (ss);
2351 if (! ((res.i == -1.0) && (res.j == -2)))
2352 return 1;
2354 return 0;
2357 typedef int (STDCALL *ArrayDelegate) (int i, char *j, void *arr);
2359 LIBTEST_API int STDCALL
2360 mono_test_marshal_array_delegate (void *arr, int len, ArrayDelegate del)
2362 return del (len, NULL, arr);
2365 typedef int (STDCALL *ArrayDelegateLong) (gint64 i, char *j, void *arr);
2367 LIBTEST_API int STDCALL
2368 mono_test_marshal_array_delegate_long (void *arr, gint64 len, ArrayDelegateLong del)
2370 return del (len, NULL, arr);
2373 LIBTEST_API int STDCALL
2374 mono_test_marshal_out_array_delegate (int *arr, int len, ArrayDelegate del)
2376 del (len, NULL, arr);
2378 if ((arr [0] != 1) || (arr [1] != 2))
2379 return 1;
2380 else
2381 return 0;
2384 typedef gunichar2* (STDCALL *UnicodeStringDelegate) (gunichar2 *message);
2386 LIBTEST_API int STDCALL
2387 mono_test_marshal_return_unicode_string_delegate (UnicodeStringDelegate del)
2389 const char m[] = "abcdef";
2390 gunichar2 *s2, *res;
2391 glong len;
2393 s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
2395 res = del (s2);
2397 marshal_free (res);
2399 return 0;
2402 LIBTEST_API int STDCALL
2403 mono_test_marshal_out_string_array_delegate (char **arr, int len, ArrayDelegate del)
2405 del (len, NULL, arr);
2407 if (!strcmp (arr [0], "ABC") && !strcmp (arr [1], "DEF"))
2408 return 0;
2409 else
2410 return 1;
2413 typedef int (*CdeclDelegate) (int i, int j);
2415 LIBTEST_API int STDCALL
2416 mono_test_marshal_cdecl_delegate (CdeclDelegate del)
2418 int i;
2420 for (i = 0; i < 1000; ++i)
2421 del (1, 2);
2423 return 0;
2426 typedef char** (STDCALL *ReturnStringArrayDelegate) (int i);
2428 LIBTEST_API int STDCALL
2429 mono_test_marshal_return_string_array_delegate (ReturnStringArrayDelegate d)
2431 char **arr = d (2);
2432 int res;
2434 if (arr == NULL)
2435 return 3;
2437 if (strcmp (arr [0], "ABC") || strcmp (arr [1], "DEF"))
2438 res = 1;
2439 else
2440 res = 0;
2442 marshal_free (arr);
2444 return res;
2447 typedef int (STDCALL *ByrefStringDelegate) (char **s);
2449 LIBTEST_API int STDCALL
2450 mono_test_marshal_byref_string_delegate (ByrefStringDelegate d)
2452 char *s = (char*)"ABC";
2453 int res;
2455 res = d (&s);
2456 if (res != 0)
2457 return res;
2459 if (!strcmp (s, "DEF"))
2460 res = 0;
2461 else
2462 res = 2;
2464 marshal_free (s);
2466 return res;
2469 LIBTEST_API int STDCALL
2470 add_delegate (int i, int j)
2472 return i + j;
2475 LIBTEST_API gpointer STDCALL
2476 mono_test_marshal_return_fnptr (void)
2478 return &add_delegate;
2481 LIBTEST_API int STDCALL
2482 mono_xr (int code)
2484 printf ("codigo %x\n", code);
2485 return code + 1234;
2488 typedef struct {
2489 int handle;
2490 } HandleRef;
2492 LIBTEST_API HandleRef STDCALL
2493 mono_xr_as_handle (int code)
2495 HandleRef ref;
2497 memset (&ref, 0, sizeof (ref));
2499 return ref;
2502 typedef struct {
2503 int a;
2504 void *handle1;
2505 void *handle2;
2506 int b;
2507 } HandleStructs;
2509 LIBTEST_API int STDCALL
2510 mono_safe_handle_struct_ref (HandleStructs *x)
2512 printf ("Dingus Ref! \n");
2513 printf ("Values: %d %d %p %p\n", x->a, x->b, x->handle1, x->handle2);
2514 if (x->a != 1234)
2515 return 1;
2516 if (x->b != 8743)
2517 return 2;
2519 if (x->handle1 != (void*) 0x7080feed)
2520 return 3;
2522 if (x->handle2 != (void*) 0x1234abcd)
2523 return 4;
2525 return 0xf00d;
2528 LIBTEST_API int STDCALL
2529 mono_safe_handle_struct (HandleStructs x)
2531 printf ("Dingus Standard! \n");
2532 printf ("Values: %d %d %p %p\n", x.a, x.b, x.handle1, x.handle2);
2533 if (x.a != 1234)
2534 return 1;
2535 if (x.b != 8743)
2536 return 2;
2538 if (x.handle1 != (void*) 0x7080feed)
2539 return 3;
2541 if (x.handle2 != (void*) 0x1234abcd)
2542 return 4;
2544 return 0xf00f;
2547 typedef struct {
2548 void *a;
2549 } TrivialHandle;
2551 LIBTEST_API int STDCALL
2552 mono_safe_handle_struct_simple (TrivialHandle x)
2554 printf ("The value is %p\n", x.a);
2555 return ((int)(gsize)x.a) * 2;
2558 LIBTEST_API int STDCALL
2559 mono_safe_handle_return (void)
2561 return 0x1000f00d;
2564 LIBTEST_API void STDCALL
2565 mono_safe_handle_ref (void **handle)
2567 if (*handle != 0){
2568 *handle = (void *) 0xbad;
2569 return;
2572 *handle = (void *) 0x800d;
2575 LIBTEST_API double STDCALL
2576 mono_test_marshal_date_time (double d, double *d2)
2578 *d2 = d;
2579 return d;
2583 * COM INTEROP TESTS
2586 #ifndef WIN32
2588 typedef struct {
2589 guint16 vt;
2590 guint16 wReserved1;
2591 guint16 wReserved2;
2592 guint16 wReserved3;
2593 union {
2594 gint64 llVal;
2595 gint32 lVal;
2596 guint8 bVal;
2597 gint16 iVal;
2598 float fltVal;
2599 double dblVal;
2600 gint16 boolVal;
2601 gunichar2* bstrVal;
2602 gint8 cVal;
2603 guint16 uiVal;
2604 guint32 ulVal;
2605 guint64 ullVal;
2606 gpointer byref;
2607 struct {
2608 gpointer pvRecord;
2609 gpointer pRecInfo;
2612 } VARIANT;
2614 typedef enum {
2615 VARIANT_TRUE = -1,
2616 VARIANT_FALSE = 0
2617 } VariantBool;
2619 typedef enum {
2620 VT_EMPTY = 0,
2621 VT_NULL = 1,
2622 VT_I2 = 2,
2623 VT_I4 = 3,
2624 VT_R4 = 4,
2625 VT_R8 = 5,
2626 VT_CY = 6,
2627 VT_DATE = 7,
2628 VT_BSTR = 8,
2629 VT_DISPATCH = 9,
2630 VT_ERROR = 10,
2631 VT_BOOL = 11,
2632 VT_VARIANT = 12,
2633 VT_UNKNOWN = 13,
2634 VT_DECIMAL = 14,
2635 VT_I1 = 16,
2636 VT_UI1 = 17,
2637 VT_UI2 = 18,
2638 VT_UI4 = 19,
2639 VT_I8 = 20,
2640 VT_UI8 = 21,
2641 VT_INT = 22,
2642 VT_UINT = 23,
2643 VT_VOID = 24,
2644 VT_HRESULT = 25,
2645 VT_PTR = 26,
2646 VT_SAFEARRAY = 27,
2647 VT_CARRAY = 28,
2648 VT_USERDEFINED = 29,
2649 VT_LPSTR = 30,
2650 VT_LPWSTR = 31,
2651 VT_RECORD = 36,
2652 VT_FILETIME = 64,
2653 VT_BLOB = 65,
2654 VT_STREAM = 66,
2655 VT_STORAGE = 67,
2656 VT_STREAMED_OBJECT = 68,
2657 VT_STORED_OBJECT = 69,
2658 VT_BLOB_OBJECT = 70,
2659 VT_CF = 71,
2660 VT_CLSID = 72,
2661 VT_VECTOR = 4096,
2662 VT_ARRAY = 8192,
2663 VT_BYREF = 16384
2664 } VarEnum;
2666 void VariantInit(VARIANT* vt)
2668 vt->vt = VT_EMPTY;
2671 typedef struct
2673 guint32 a;
2674 guint16 b;
2675 guint16 c;
2676 guint8 d[8];
2677 } GUID;
2679 #define S_OK 0
2681 #endif
2683 LIBTEST_API int STDCALL
2684 mono_test_marshal_bstr_in(gunichar2* bstr)
2686 gint32 result = 0;
2687 gchar* bstr_utf8 = g_utf16_to_utf8 (bstr, -1, NULL, NULL, NULL);
2688 result = strcmp("mono_test_marshal_bstr_in", bstr_utf8);
2689 g_free(bstr_utf8);
2690 if (result == 0)
2691 return 0;
2692 return 1;
2695 LIBTEST_API int STDCALL
2696 mono_test_marshal_bstr_out(gunichar2** bstr)
2698 *bstr = marshal_bstr_alloc ("mono_test_marshal_bstr_out");
2699 return 0;
2702 LIBTEST_API int STDCALL
2703 mono_test_marshal_bstr_in_null(gunichar2* bstr)
2705 if (!bstr)
2706 return 0;
2707 return 1;
2710 LIBTEST_API int STDCALL
2711 mono_test_marshal_bstr_out_null(gunichar2** bstr)
2713 *bstr = NULL;
2714 return 0;
2717 LIBTEST_API int STDCALL
2718 mono_test_marshal_variant_in_sbyte(VARIANT variant)
2720 if (variant.vt == VT_I1 && variant.cVal == 100)
2721 return 0;
2722 return 1;
2725 LIBTEST_API int STDCALL
2726 mono_test_marshal_variant_in_byte(VARIANT variant)
2728 if (variant.vt == VT_UI1 && variant.bVal == 100)
2729 return 0;
2730 return 1;
2733 LIBTEST_API int STDCALL
2734 mono_test_marshal_variant_in_short(VARIANT variant)
2736 if (variant.vt == VT_I2 && variant.iVal == 314)
2737 return 0;
2738 return 1;
2741 LIBTEST_API int STDCALL
2742 mono_test_marshal_variant_in_ushort(VARIANT variant)
2744 if (variant.vt == VT_UI2 && variant.uiVal == 314)
2745 return 0;
2746 return 1;
2749 LIBTEST_API int STDCALL
2750 mono_test_marshal_variant_in_int(VARIANT variant)
2752 if (variant.vt == VT_I4 && variant.lVal == 314)
2753 return 0;
2754 return 1;
2757 LIBTEST_API int STDCALL
2758 mono_test_marshal_variant_in_uint(VARIANT variant)
2760 if (variant.vt == VT_UI4 && variant.ulVal == 314)
2761 return 0;
2762 return 1;
2765 LIBTEST_API int STDCALL
2766 mono_test_marshal_variant_in_long(VARIANT variant)
2768 if (variant.vt == VT_I8 && variant.llVal == 314)
2769 return 0;
2770 return 1;
2773 LIBTEST_API int STDCALL
2774 mono_test_marshal_variant_in_ulong(VARIANT variant)
2776 if (variant.vt == VT_UI8 && variant.ullVal == 314)
2777 return 0;
2778 return 1;
2781 LIBTEST_API int STDCALL
2782 mono_test_marshal_variant_in_float(VARIANT variant)
2784 if (variant.vt == VT_R4 && (variant.fltVal - 3.14)/3.14 < .001)
2785 return 0;
2786 return 1;
2789 LIBTEST_API int STDCALL
2790 mono_test_marshal_variant_in_double(VARIANT variant)
2792 if (variant.vt == VT_R8 && (variant.dblVal - 3.14)/3.14 < .001)
2793 return 0;
2794 return 1;
2797 LIBTEST_API int STDCALL
2798 mono_test_marshal_variant_in_bstr(VARIANT variant)
2800 gint32 result = 0;
2801 gchar* bstr_utf8 = g_utf16_to_utf8 (variant.bstrVal, -1, NULL, NULL, NULL);
2802 result = strcmp("PI", bstr_utf8);
2803 g_free(bstr_utf8);
2805 if (variant.vt == VT_BSTR && !result)
2806 return 0;
2807 return 1;
2810 LIBTEST_API int STDCALL
2811 mono_test_marshal_variant_in_bool_true (VARIANT variant)
2813 if (variant.vt == VT_BOOL && variant.boolVal == VARIANT_TRUE)
2814 return 0;
2815 return 1;
2818 LIBTEST_API int STDCALL
2819 mono_test_marshal_variant_in_bool_false (VARIANT variant)
2821 if (variant.vt == VT_BOOL && variant.boolVal == VARIANT_FALSE)
2822 return 0;
2823 return 1;
2826 LIBTEST_API int STDCALL
2827 mono_test_marshal_variant_out_sbyte(VARIANT* variant)
2829 variant->vt = VT_I1;
2830 variant->cVal = 100;
2832 return 0;
2835 LIBTEST_API int STDCALL
2836 mono_test_marshal_variant_out_sbyte_byref(VARIANT* variant)
2838 variant->vt = VT_I1|VT_BYREF;
2839 variant->byref = marshal_alloc(1);
2840 *((gint8*)variant->byref) = 100;
2842 return 0;
2845 LIBTEST_API int STDCALL
2846 mono_test_marshal_variant_out_byte(VARIANT* variant)
2848 variant->vt = VT_UI1;
2849 variant->bVal = 100;
2851 return 0;
2854 LIBTEST_API int STDCALL
2855 mono_test_marshal_variant_out_byte_byref(VARIANT* variant)
2857 variant->vt = VT_UI1|VT_BYREF;
2858 variant->byref = marshal_alloc(1);
2859 *((gint8*)variant->byref) = 100;
2861 return 0;
2864 LIBTEST_API int STDCALL
2865 mono_test_marshal_variant_out_short(VARIANT* variant)
2867 variant->vt = VT_I2;
2868 variant->iVal = 314;
2870 return 0;
2873 LIBTEST_API int STDCALL
2874 mono_test_marshal_variant_out_short_byref(VARIANT* variant)
2876 variant->vt = VT_I2|VT_BYREF;
2877 variant->byref = marshal_alloc(2);
2878 *((gint16*)variant->byref) = 314;
2880 return 0;
2883 LIBTEST_API int STDCALL
2884 mono_test_marshal_variant_out_ushort(VARIANT* variant)
2886 variant->vt = VT_UI2;
2887 variant->uiVal = 314;
2889 return 0;
2892 LIBTEST_API int STDCALL
2893 mono_test_marshal_variant_out_ushort_byref(VARIANT* variant)
2895 variant->vt = VT_UI2|VT_BYREF;
2896 variant->byref = marshal_alloc(2);
2897 *((guint16*)variant->byref) = 314;
2899 return 0;
2902 LIBTEST_API int STDCALL
2903 mono_test_marshal_variant_out_int(VARIANT* variant)
2905 variant->vt = VT_I4;
2906 variant->lVal = 314;
2908 return 0;
2911 LIBTEST_API int STDCALL
2912 mono_test_marshal_variant_out_int_byref(VARIANT* variant)
2914 variant->vt = VT_I4|VT_BYREF;
2915 variant->byref = marshal_alloc(4);
2916 *((gint32*)variant->byref) = 314;
2918 return 0;
2921 LIBTEST_API int STDCALL
2922 mono_test_marshal_variant_out_uint(VARIANT* variant)
2924 variant->vt = VT_UI4;
2925 variant->ulVal = 314;
2927 return 0;
2930 LIBTEST_API int STDCALL
2931 mono_test_marshal_variant_out_uint_byref(VARIANT* variant)
2933 variant->vt = VT_UI4|VT_BYREF;
2934 variant->byref = marshal_alloc(4);
2935 *((guint32*)variant->byref) = 314;
2937 return 0;
2940 LIBTEST_API int STDCALL
2941 mono_test_marshal_variant_out_long(VARIANT* variant)
2943 variant->vt = VT_I8;
2944 variant->llVal = 314;
2946 return 0;
2949 LIBTEST_API int STDCALL
2950 mono_test_marshal_variant_out_long_byref(VARIANT* variant)
2952 variant->vt = VT_I8|VT_BYREF;
2953 variant->byref = marshal_alloc(8);
2954 *((gint64*)variant->byref) = 314;
2956 return 0;
2959 LIBTEST_API int STDCALL
2960 mono_test_marshal_variant_out_ulong(VARIANT* variant)
2962 variant->vt = VT_UI8;
2963 variant->ullVal = 314;
2965 return 0;
2968 LIBTEST_API int STDCALL
2969 mono_test_marshal_variant_out_ulong_byref(VARIANT* variant)
2971 variant->vt = VT_UI8|VT_BYREF;
2972 variant->byref = marshal_alloc(8);
2973 *((guint64*)variant->byref) = 314;
2975 return 0;
2978 LIBTEST_API int STDCALL
2979 mono_test_marshal_variant_out_float(VARIANT* variant)
2981 variant->vt = VT_R4;
2982 variant->fltVal = 3.14;
2984 return 0;
2987 LIBTEST_API int STDCALL
2988 mono_test_marshal_variant_out_float_byref(VARIANT* variant)
2990 variant->vt = VT_R4|VT_BYREF;
2991 variant->byref = marshal_alloc(4);
2992 *((float*)variant->byref) = 3.14;
2994 return 0;
2997 LIBTEST_API int STDCALL
2998 mono_test_marshal_variant_out_double(VARIANT* variant)
3000 variant->vt = VT_R8;
3001 variant->dblVal = 3.14;
3003 return 0;
3006 LIBTEST_API int STDCALL
3007 mono_test_marshal_variant_out_double_byref(VARIANT* variant)
3009 variant->vt = VT_R8|VT_BYREF;
3010 variant->byref = marshal_alloc(8);
3011 *((double*)variant->byref) = 3.14;
3013 return 0;
3016 LIBTEST_API int STDCALL
3017 mono_test_marshal_variant_out_bstr(VARIANT* variant)
3019 variant->vt = VT_BSTR;
3020 variant->bstrVal = marshal_bstr_alloc("PI");
3022 return 0;
3025 LIBTEST_API int STDCALL
3026 mono_test_marshal_variant_out_bstr_byref(VARIANT* variant)
3028 variant->vt = VT_BSTR|VT_BYREF;
3029 variant->byref = marshal_alloc(sizeof(gpointer));
3030 *((gunichar**)variant->byref) = (gunichar*)marshal_bstr_alloc("PI");
3032 return 0;
3035 LIBTEST_API int STDCALL
3036 mono_test_marshal_variant_out_bool_true (VARIANT* variant)
3038 variant->vt = VT_BOOL;
3039 variant->boolVal = VARIANT_TRUE;
3041 return 0;
3044 LIBTEST_API int STDCALL
3045 mono_test_marshal_variant_out_bool_true_byref (VARIANT* variant)
3047 variant->vt = VT_BOOL|VT_BYREF;
3048 variant->byref = marshal_alloc(2);
3049 *((gint16*)variant->byref) = VARIANT_TRUE;
3051 return 0;
3054 LIBTEST_API int STDCALL
3055 mono_test_marshal_variant_out_bool_false (VARIANT* variant)
3057 variant->vt = VT_BOOL;
3058 variant->boolVal = VARIANT_FALSE;
3060 return 0;
3063 LIBTEST_API int STDCALL
3064 mono_test_marshal_variant_out_bool_false_byref (VARIANT* variant)
3066 variant->vt = VT_BOOL|VT_BYREF;
3067 variant->byref = marshal_alloc(2);
3068 *((gint16*)variant->byref) = VARIANT_FALSE;
3070 return 0;
3073 typedef int (STDCALL *VarFunc) (int vt, VARIANT variant);
3074 typedef int (STDCALL *VarRefFunc) (int vt, VARIANT* variant);
3076 LIBTEST_API int STDCALL
3077 mono_test_marshal_variant_in_sbyte_unmanaged(VarFunc func)
3079 VARIANT vt;
3080 vt.vt = VT_I1;
3081 vt.cVal = -100;
3082 return func (VT_I1, vt);
3085 LIBTEST_API int STDCALL
3086 mono_test_marshal_variant_in_byte_unmanaged(VarFunc func)
3088 VARIANT vt;
3089 vt.vt = VT_UI1;
3090 vt.bVal = 100;
3091 return func (VT_UI1, vt);
3094 LIBTEST_API int STDCALL
3095 mono_test_marshal_variant_in_short_unmanaged(VarFunc func)
3097 VARIANT vt;
3098 vt.vt = VT_I2;
3099 vt.iVal = -100;
3100 return func (VT_I2, vt);
3103 LIBTEST_API int STDCALL
3104 mono_test_marshal_variant_in_ushort_unmanaged(VarFunc func)
3106 VARIANT vt;
3107 vt.vt = VT_UI2;
3108 vt.uiVal = 100;
3109 return func (VT_UI2, vt);
3112 LIBTEST_API int STDCALL
3113 mono_test_marshal_variant_in_int_unmanaged(VarFunc func)
3115 VARIANT vt;
3116 vt.vt = VT_I4;
3117 vt.lVal = -100;
3118 return func (VT_I4, vt);
3121 LIBTEST_API int STDCALL
3122 mono_test_marshal_variant_in_uint_unmanaged(VarFunc func)
3124 VARIANT vt;
3125 vt.vt = VT_UI4;
3126 vt.ulVal = 100;
3127 return func (VT_UI4, vt);
3130 LIBTEST_API int STDCALL
3131 mono_test_marshal_variant_in_long_unmanaged(VarFunc func)
3133 VARIANT vt;
3134 vt.vt = VT_I8;
3135 vt.llVal = -100;
3136 return func (VT_I8, vt);
3139 LIBTEST_API int STDCALL
3140 mono_test_marshal_variant_in_ulong_unmanaged(VarFunc func)
3142 VARIANT vt;
3143 vt.vt = VT_UI8;
3144 vt.ullVal = 100;
3145 return func (VT_UI8, vt);
3148 LIBTEST_API int STDCALL
3149 mono_test_marshal_variant_in_float_unmanaged(VarFunc func)
3151 VARIANT vt;
3152 vt.vt = VT_R4;
3153 vt.fltVal = 3.14;
3154 return func (VT_R4, vt);
3157 LIBTEST_API int STDCALL
3158 mono_test_marshal_variant_in_double_unmanaged(VarFunc func)
3160 VARIANT vt;
3161 vt.vt = VT_R8;
3162 vt.dblVal = 3.14;
3163 return func (VT_R8, vt);
3166 LIBTEST_API int STDCALL
3167 mono_test_marshal_variant_in_bstr_unmanaged(VarFunc func)
3169 VARIANT vt;
3170 vt.vt = VT_BSTR;
3171 vt.bstrVal = marshal_bstr_alloc("PI");
3172 return func (VT_BSTR, vt);
3175 LIBTEST_API int STDCALL
3176 mono_test_marshal_variant_in_bool_true_unmanaged(VarFunc func)
3178 VARIANT vt;
3179 vt.vt = VT_BOOL;
3180 vt.boolVal = VARIANT_TRUE;
3181 return func (VT_BOOL, vt);
3184 LIBTEST_API int STDCALL
3185 mono_test_marshal_variant_in_bool_false_unmanaged(VarFunc func)
3187 VARIANT vt;
3188 vt.vt = VT_BOOL;
3189 vt.boolVal = VARIANT_FALSE;
3190 return func (VT_BOOL, vt);
3193 LIBTEST_API int STDCALL
3194 mono_test_marshal_variant_out_sbyte_unmanaged(VarRefFunc func)
3196 VARIANT vt;
3197 VariantInit (&vt);
3198 func (VT_I1, &vt);
3199 if (vt.vt == VT_I1 && vt.cVal == -100)
3200 return 0;
3201 return 1;
3204 LIBTEST_API int STDCALL
3205 mono_test_marshal_variant_out_byte_unmanaged(VarRefFunc func)
3207 VARIANT vt;
3208 VariantInit (&vt);
3209 func (VT_UI1, &vt);
3210 if (vt.vt == VT_UI1 && vt.bVal == 100)
3211 return 0;
3212 return 1;
3215 LIBTEST_API int STDCALL
3216 mono_test_marshal_variant_out_short_unmanaged(VarRefFunc func)
3218 VARIANT vt;
3219 VariantInit (&vt);
3220 func (VT_I2, &vt);
3221 if (vt.vt == VT_I2 && vt.iVal == -100)
3222 return 0;
3223 return 1;
3226 LIBTEST_API int STDCALL
3227 mono_test_marshal_variant_out_ushort_unmanaged(VarRefFunc func)
3229 VARIANT vt;
3230 VariantInit (&vt);
3231 func (VT_UI2, &vt);
3232 if (vt.vt == VT_UI2 && vt.uiVal == 100)
3233 return 0;
3234 return 1;
3237 LIBTEST_API int STDCALL
3238 mono_test_marshal_variant_out_int_unmanaged(VarRefFunc func)
3240 VARIANT vt;
3241 VariantInit (&vt);
3242 func (VT_I4, &vt);
3243 if (vt.vt == VT_I4 && vt.lVal == -100)
3244 return 0;
3245 return 1;
3248 LIBTEST_API int STDCALL
3249 mono_test_marshal_variant_out_uint_unmanaged(VarRefFunc func)
3251 VARIANT vt;
3252 VariantInit (&vt);
3253 func (VT_UI4, &vt);
3254 if (vt.vt == VT_UI4 && vt.ulVal == 100)
3255 return 0;
3256 return 1;
3259 LIBTEST_API int STDCALL
3260 mono_test_marshal_variant_out_long_unmanaged(VarRefFunc func)
3262 VARIANT vt;
3263 VariantInit (&vt);
3264 func (VT_I8, &vt);
3265 if (vt.vt == VT_I8 && vt.llVal == -100)
3266 return 0;
3267 return 1;
3270 LIBTEST_API int STDCALL
3271 mono_test_marshal_variant_out_ulong_unmanaged(VarRefFunc func)
3273 VARIANT vt;
3274 VariantInit (&vt);
3275 func (VT_UI8, &vt);
3276 if (vt.vt == VT_UI8 && vt.ullVal == 100)
3277 return 0;
3278 return 1;
3281 LIBTEST_API int STDCALL
3282 mono_test_marshal_variant_out_float_unmanaged(VarRefFunc func)
3284 VARIANT vt;
3285 VariantInit (&vt);
3286 func (VT_R4, &vt);
3287 if (vt.vt == VT_R4 && fabs (vt.fltVal - 3.14f) < 1e-10)
3288 return 0;
3289 return 1;
3292 LIBTEST_API int STDCALL
3293 mono_test_marshal_variant_out_double_unmanaged(VarRefFunc func)
3295 VARIANT vt;
3296 VariantInit (&vt);
3297 func (VT_R8, &vt);
3298 if (vt.vt == VT_R8 && fabs (vt.dblVal - 3.14) < 1e-10)
3299 return 0;
3300 return 1;
3303 LIBTEST_API int STDCALL
3304 mono_test_marshal_variant_out_bstr_unmanaged(VarRefFunc func)
3306 VARIANT vt;
3307 gchar* bstr_utf8;
3308 gint32 result = 0;
3311 VariantInit (&vt);
3312 func (VT_BSTR, &vt);
3313 bstr_utf8 = g_utf16_to_utf8 (vt.bstrVal, -1, NULL, NULL, NULL);
3314 result = strcmp("PI", bstr_utf8);
3315 g_free(bstr_utf8);
3316 if (vt.vt == VT_BSTR && !result)
3317 return 0;
3318 return 1;
3321 LIBTEST_API int STDCALL
3322 mono_test_marshal_variant_out_bool_true_unmanaged(VarRefFunc func)
3324 VARIANT vt;
3325 VariantInit (&vt);
3326 func (VT_BOOL, &vt);
3327 if (vt.vt == VT_BOOL && vt.boolVal == VARIANT_TRUE)
3328 return 0;
3329 return 1;
3332 LIBTEST_API int STDCALL
3333 mono_test_marshal_variant_out_bool_false_unmanaged(VarRefFunc func)
3335 VARIANT vt;
3336 VariantInit (&vt);
3337 func (VT_BOOL, &vt);
3338 if (vt.vt == VT_BOOL && vt.boolVal == VARIANT_TRUE)
3339 return 0;
3340 return 1;
3343 typedef struct MonoComObject MonoComObject;
3345 typedef struct
3347 int (STDCALL *QueryInterface)(MonoComObject* pUnk, gpointer riid, gpointer* ppv);
3348 int (STDCALL *AddRef)(MonoComObject* pUnk);
3349 int (STDCALL *Release)(MonoComObject* pUnk);
3350 int (STDCALL *get_ITest)(MonoComObject* pUnk, MonoComObject* *ppUnk);
3351 int (STDCALL *SByteIn)(MonoComObject* pUnk, char a);
3352 int (STDCALL *ByteIn)(MonoComObject* pUnk, unsigned char a);
3353 int (STDCALL *ShortIn)(MonoComObject* pUnk, short a);
3354 int (STDCALL *UShortIn)(MonoComObject* pUnk, unsigned short a);
3355 int (STDCALL *IntIn)(MonoComObject* pUnk, int a);
3356 int (STDCALL *UIntIn)(MonoComObject* pUnk, unsigned int a);
3357 int (STDCALL *LongIn)(MonoComObject* pUnk, gint64 a);
3358 int (STDCALL *ULongIn)(MonoComObject* pUnk, guint64 a);
3359 int (STDCALL *FloatIn)(MonoComObject* pUnk, float a);
3360 int (STDCALL *DoubleIn)(MonoComObject* pUnk, double a);
3361 int (STDCALL *ITestIn)(MonoComObject* pUnk, MonoComObject* pUnk2);
3362 int (STDCALL *ITestOut)(MonoComObject* pUnk, MonoComObject* *ppUnk);
3363 int (STDCALL *Return22NoICall)(MonoComObject* pUnk);
3364 } MonoIUnknown;
3366 struct MonoComObject
3368 MonoIUnknown* vtbl;
3369 int m_ref;
3372 static GUID IID_ITest = {0, 0, 0, {0,0,0,0,0,0,0,1}};
3373 static GUID IID_IMonoUnknown = {0, 0, 0, {0xc0,0,0,0,0,0,0,0x46}};
3374 static GUID IID_IMonoDispatch = {0x00020400, 0, 0, {0xc0,0,0,0,0,0,0,0x46}};
3376 LIBTEST_API int STDCALL
3377 MonoQueryInterface(MonoComObject* pUnk, gpointer riid, gpointer* ppv)
3380 *ppv = NULL;
3381 if (!memcmp(riid, &IID_IMonoUnknown, sizeof(GUID))) {
3382 *ppv = pUnk;
3383 return S_OK;
3385 else if (!memcmp(riid, &IID_ITest, sizeof(GUID))) {
3386 *ppv = pUnk;
3387 return S_OK;
3389 else if (!memcmp(riid, &IID_IMonoDispatch, sizeof(GUID))) {
3390 *ppv = pUnk;
3391 return S_OK;
3393 return 0x80004002; //E_NOINTERFACE;
3396 LIBTEST_API int STDCALL
3397 MonoAddRef(MonoComObject* pUnk)
3399 return ++(pUnk->m_ref);
3402 LIBTEST_API int STDCALL
3403 MonoRelease(MonoComObject* pUnk)
3405 return --(pUnk->m_ref);
3408 LIBTEST_API int STDCALL
3409 SByteIn(MonoComObject* pUnk, char a)
3411 return S_OK;
3414 LIBTEST_API int STDCALL
3415 ByteIn(MonoComObject* pUnk, unsigned char a)
3417 return S_OK;
3420 LIBTEST_API int STDCALL
3421 ShortIn(MonoComObject* pUnk, short a)
3423 return S_OK;
3426 LIBTEST_API int STDCALL
3427 UShortIn(MonoComObject* pUnk, unsigned short a)
3429 return S_OK;
3432 LIBTEST_API int STDCALL
3433 IntIn(MonoComObject* pUnk, int a)
3435 return S_OK;
3438 LIBTEST_API int STDCALL
3439 UIntIn(MonoComObject* pUnk, unsigned int a)
3441 return S_OK;
3444 LIBTEST_API int STDCALL
3445 LongIn(MonoComObject* pUnk, gint64 a)
3447 return S_OK;
3450 LIBTEST_API int STDCALL
3451 ULongIn(MonoComObject* pUnk, guint64 a)
3453 return S_OK;
3456 LIBTEST_API int STDCALL
3457 FloatIn(MonoComObject* pUnk, float a)
3459 return S_OK;
3462 LIBTEST_API int STDCALL
3463 DoubleIn(MonoComObject* pUnk, double a)
3465 return S_OK;
3468 LIBTEST_API int STDCALL
3469 ITestIn(MonoComObject* pUnk, MonoComObject *pUnk2)
3471 return S_OK;
3474 LIBTEST_API int STDCALL
3475 ITestOut(MonoComObject* pUnk, MonoComObject* *ppUnk)
3477 return S_OK;
3480 LIBTEST_API int STDCALL
3481 Return22NoICall(MonoComObject* pUnk)
3483 return 22;
3487 static void create_com_object (MonoComObject** pOut);
3489 LIBTEST_API int STDCALL
3490 get_ITest(MonoComObject* pUnk, MonoComObject* *ppUnk)
3492 create_com_object (ppUnk);
3493 return S_OK;
3496 static void create_com_object (MonoComObject** pOut)
3498 *pOut = marshal_new0 (MonoComObject, 1);
3499 (*pOut)->vtbl = marshal_new0 (MonoIUnknown, 1);
3501 (*pOut)->m_ref = 1;
3502 (*pOut)->vtbl->QueryInterface = MonoQueryInterface;
3503 (*pOut)->vtbl->AddRef = MonoAddRef;
3504 (*pOut)->vtbl->Release = MonoRelease;
3505 (*pOut)->vtbl->SByteIn = SByteIn;
3506 (*pOut)->vtbl->ByteIn = ByteIn;
3507 (*pOut)->vtbl->ShortIn = ShortIn;
3508 (*pOut)->vtbl->UShortIn = UShortIn;
3509 (*pOut)->vtbl->IntIn = IntIn;
3510 (*pOut)->vtbl->UIntIn = UIntIn;
3511 (*pOut)->vtbl->LongIn = LongIn;
3512 (*pOut)->vtbl->ULongIn = ULongIn;
3513 (*pOut)->vtbl->FloatIn = FloatIn;
3514 (*pOut)->vtbl->DoubleIn = DoubleIn;
3515 (*pOut)->vtbl->ITestIn = ITestIn;
3516 (*pOut)->vtbl->ITestOut = ITestOut;
3517 (*pOut)->vtbl->get_ITest = get_ITest;
3518 (*pOut)->vtbl->Return22NoICall = Return22NoICall;
3521 static MonoComObject* same_object = NULL;
3523 LIBTEST_API int STDCALL
3524 mono_test_marshal_com_object_create(MonoComObject* *pUnk)
3526 create_com_object (pUnk);
3528 if (!same_object)
3529 same_object = *pUnk;
3531 return 0;
3534 LIBTEST_API int STDCALL
3535 mono_test_marshal_com_object_same(MonoComObject* *pUnk)
3537 *pUnk = same_object;
3539 return 0;
3542 LIBTEST_API int STDCALL
3543 mono_test_marshal_com_object_destroy(MonoComObject *pUnk)
3545 int ref = --(pUnk->m_ref);
3546 g_free(pUnk->vtbl);
3547 g_free(pUnk);
3549 return ref;
3552 LIBTEST_API int STDCALL
3553 mono_test_marshal_com_object_ref_count(MonoComObject *pUnk)
3555 return pUnk->m_ref;
3558 LIBTEST_API int STDCALL
3559 mono_test_marshal_ccw_itest (MonoComObject *pUnk)
3561 int hr = 0;
3562 MonoComObject* pTest;
3564 if (!pUnk)
3565 return 1;
3567 hr = pUnk->vtbl->SByteIn (pUnk, -100);
3568 if (hr != 0)
3569 return 2;
3570 hr = pUnk->vtbl->ByteIn (pUnk, 100);
3571 if (hr != 0)
3572 return 3;
3573 hr = pUnk->vtbl->ShortIn (pUnk, -100);
3574 if (hr != 0)
3575 return 4;
3576 hr = pUnk->vtbl->UShortIn (pUnk, 100);
3577 if (hr != 0)
3578 return 5;
3579 hr = pUnk->vtbl->IntIn (pUnk, -100);
3580 if (hr != 0)
3581 return 6;
3582 hr = pUnk->vtbl->UIntIn (pUnk, 100);
3583 if (hr != 0)
3584 return 7;
3585 hr = pUnk->vtbl->LongIn (pUnk, -100);
3586 if (hr != 0)
3587 return 8;
3588 hr = pUnk->vtbl->ULongIn (pUnk, 100);
3589 if (hr != 0)
3590 return 9;
3591 hr = pUnk->vtbl->FloatIn (pUnk, 3.14f);
3592 if (hr != 0)
3593 return 10;
3594 hr = pUnk->vtbl->DoubleIn (pUnk, 3.14);
3595 if (hr != 0)
3596 return 11;
3597 hr = pUnk->vtbl->ITestIn (pUnk, pUnk);
3598 if (hr != 0)
3599 return 12;
3600 hr = pUnk->vtbl->ITestOut (pUnk, &pTest);
3601 if (hr != 0)
3602 return 13;
3604 return 0;
3607 // Xamarin-47560
3608 LIBTEST_API int STDCALL
3609 mono_test_marshal_array_ccw_itest (int count, MonoComObject ** ppUnk)
3611 int hr = 0;
3613 if (!ppUnk)
3614 return 1;
3616 if (count < 1)
3617 return 2;
3619 if (!ppUnk[0])
3620 return 3;
3622 hr = ppUnk[0]->vtbl->SByteIn (ppUnk[0], -100);
3623 if (hr != 0)
3624 return 4;
3626 return 0;
3630 * mono_method_get_unmanaged_thunk tests
3633 #if defined(__GNUC__) && ((defined(__i386__) && (defined(__linux__) || defined (__APPLE__)) || defined (__FreeBSD__) || defined(__OpenBSD__)) || (defined(__ppc__) && defined(__APPLE__)))
3634 #define ALIGN(size) __attribute__ ((__aligned__(size)))
3635 #else
3636 #define ALIGN(size)
3637 #endif
3640 /* thunks.cs:TestStruct */
3641 typedef struct _TestStruct {
3642 int A;
3643 double B;
3644 } TestStruct;
3646 /* Searches for mono symbols in all loaded modules */
3647 static gpointer
3648 lookup_mono_symbol (const char *symbol_name)
3650 gpointer symbol;
3651 if (g_module_symbol (g_module_open (NULL, G_MODULE_BIND_LAZY), symbol_name, &symbol))
3652 return symbol;
3653 else
3654 return NULL;
3657 LIBTEST_API gpointer STDCALL
3658 mono_test_marshal_lookup_symbol (const char *symbol_name)
3660 return lookup_mono_symbol (symbol_name);
3664 // FIXME use runtime headers
3665 #define MONO_BEGIN_EFRAME { void *__dummy; void *__region_cookie = mono_threads_enter_gc_unsafe_region ? mono_threads_enter_gc_unsafe_region (&__dummy) : NULL;
3666 #define MONO_END_EFRAME if (mono_threads_exit_gc_unsafe_region) mono_threads_exit_gc_unsafe_region (__region_cookie, &__dummy); }
3669 * test_method_thunk:
3671 * @test_id: the test number
3672 * @test_method_handle: MonoMethod* of the C# test method
3673 * @create_object_method_handle: MonoMethod* of thunks.cs:Test.CreateObject
3675 LIBTEST_API int STDCALL
3676 test_method_thunk (int test_id, gpointer test_method_handle, gpointer create_object_method_handle)
3678 int ret = 0;
3680 // FIXME use runtime headers
3681 gpointer (*mono_method_get_unmanaged_thunk)(gpointer)
3682 = (gpointer (*)(gpointer))lookup_mono_symbol ("mono_method_get_unmanaged_thunk");
3684 // FIXME use runtime headers
3685 gpointer (*mono_string_new_wrapper)(const char *)
3686 = (gpointer (*)(const char *))lookup_mono_symbol ("mono_string_new_wrapper");
3688 // FIXME use runtime headers
3689 char *(*mono_string_to_utf8)(gpointer)
3690 = (char *(*)(gpointer))lookup_mono_symbol ("mono_string_to_utf8");
3692 // FIXME use runtime headers
3693 gpointer (*mono_object_unbox)(gpointer)
3694 = (gpointer (*)(gpointer))lookup_mono_symbol ("mono_object_unbox");
3696 // FIXME use runtime headers
3697 gpointer (*mono_threads_enter_gc_unsafe_region) (gpointer)
3698 = (gpointer (*)(gpointer))lookup_mono_symbol ("mono_threads_enter_gc_unsafe_region");
3700 // FIXME use runtime headers
3701 void (*mono_threads_exit_gc_unsafe_region) (gpointer, gpointer)
3702 = (void (*)(gpointer, gpointer))lookup_mono_symbol ("mono_threads_exit_gc_unsafe_region");
3706 gpointer test_method, ex = NULL;
3707 gpointer (STDCALL *CreateObject)(gpointer*);
3709 MONO_BEGIN_EFRAME;
3711 if (!mono_method_get_unmanaged_thunk) {
3712 ret = 1;
3713 goto done;
3716 test_method = mono_method_get_unmanaged_thunk (test_method_handle);
3717 if (!test_method) {
3718 ret = 2;
3719 goto done;
3722 CreateObject = (gpointer (STDCALL *)(gpointer *))mono_method_get_unmanaged_thunk (create_object_method_handle);
3723 if (!CreateObject) {
3724 ret = 3;
3725 goto done;
3729 switch (test_id) {
3731 case 0: {
3732 /* thunks.cs:Test.Test0 */
3733 void (STDCALL *F)(gpointer *) = (void (STDCALL *)(gpointer *))test_method;
3734 F (&ex);
3735 break;
3738 case 1: {
3739 /* thunks.cs:Test.Test1 */
3740 int (STDCALL *F)(gpointer *) = (int (STDCALL *)(gpointer *))test_method;
3741 if (F (&ex) != 42) {
3742 ret = 4;
3743 goto done;
3745 break;
3748 case 2: {
3749 /* thunks.cs:Test.Test2 */
3750 gpointer (STDCALL *F)(gpointer, gpointer*) = (gpointer (STDCALL *)(gpointer, gpointer *))test_method;
3751 gpointer str = mono_string_new_wrapper ("foo");
3752 if (str != F (str, &ex)) {
3753 ret = 4;
3754 goto done;
3756 break;
3759 case 3: {
3760 /* thunks.cs:Test.Test3 */
3761 gpointer (STDCALL *F)(gpointer, gpointer, gpointer*);
3762 gpointer obj;
3763 gpointer str;
3765 F = (gpointer (STDCALL *)(gpointer, gpointer, gpointer *))test_method;
3766 obj = CreateObject (&ex);
3767 str = mono_string_new_wrapper ("bar");
3769 if (str != F (obj, str, &ex)) {
3770 ret = 4;
3771 goto done;
3773 break;
3776 case 4: {
3777 /* thunks.cs:Test.Test4 */
3778 int (STDCALL *F)(gpointer, gpointer, int, gpointer*);
3779 gpointer obj;
3780 gpointer str;
3782 F = (int (STDCALL *)(gpointer, gpointer, int, gpointer *))test_method;
3783 obj = CreateObject (&ex);
3784 str = mono_string_new_wrapper ("bar");
3786 if (42 != F (obj, str, 42, &ex)) {
3787 ret = 4;
3788 goto done;
3791 break;
3794 case 5: {
3795 /* thunks.cs:Test.Test5 */
3796 int (STDCALL *F)(gpointer, gpointer, int, gpointer*);
3797 gpointer obj;
3798 gpointer str;
3800 F = (int (STDCALL *)(gpointer, gpointer, int, gpointer *))test_method;
3801 obj = CreateObject (&ex);
3802 str = mono_string_new_wrapper ("bar");
3804 F (obj, str, 42, &ex);
3805 if (!ex) {
3806 ret = 4;
3807 goto done;
3810 break;
3813 case 6: {
3814 /* thunks.cs:Test.Test6 */
3815 int (STDCALL *F)(gpointer, guint8, gint16, gint32, gint64, float, double,
3816 gpointer, gpointer*);
3817 gpointer obj;
3818 gpointer str = mono_string_new_wrapper ("Test6");
3819 int res;
3821 F = (int (STDCALL *)(gpointer, guint8, gint16, gint32, gint64, float, double, gpointer, gpointer *))test_method;
3822 obj = CreateObject (&ex);
3824 res = F (obj, 254, 32700, -245378, 6789600, 3.1415, 3.1415, str, &ex);
3825 if (ex) {
3826 ret = 4;
3827 goto done;
3830 if (!res) {
3831 ret = 5;
3832 goto done;
3835 break;
3838 case 7: {
3839 /* thunks.cs:Test.Test7 */
3840 gint64 (STDCALL *F)(gpointer*) = (gint64 (STDCALL *)(gpointer *))test_method;
3841 if (F (&ex) != G_MAXINT64) {
3842 ret = 4;
3843 goto done;
3845 break;
3848 case 8: {
3849 /* thunks.cs:Test.Test8 */
3850 void (STDCALL *F)(guint8*, gint16*, gint32*, gint64*, float*, double*,
3851 gpointer*, gpointer*);
3853 guint8 a1;
3854 gint16 a2;
3855 gint32 a3;
3856 gint64 a4;
3857 float a5;
3858 double a6;
3859 gpointer a7;
3861 F = (void (STDCALL *)(guint8 *, gint16 *, gint32 *, gint64 *, float *, double *,
3862 gpointer *, gpointer *))test_method;
3864 F (&a1, &a2, &a3, &a4, &a5, &a6, &a7, &ex);
3865 if (ex) {
3866 ret = 4;
3867 goto done;
3870 if (!(a1 == 254 &&
3871 a2 == 32700 &&
3872 a3 == -245378 &&
3873 a4 == 6789600 &&
3874 (fabs (a5 - 3.1415) < 0.001) &&
3875 (fabs (a6 - 3.1415) < 0.001) &&
3876 strcmp (mono_string_to_utf8 (a7), "Test8") == 0)){
3877 ret = 5;
3878 goto done;
3881 break;
3884 case 9: {
3885 /* thunks.cs:Test.Test9 */
3886 void (STDCALL *F)(guint8*, gint16*, gint32*, gint64*, float*, double*,
3887 gpointer*, gpointer*);
3889 guint8 a1;
3890 gint16 a2;
3891 gint32 a3;
3892 gint64 a4;
3893 float a5;
3894 double a6;
3895 gpointer a7;
3897 F = (void (STDCALL *)(guint8 *, gint16 *, gint32 *, gint64 *, float *, double *,
3898 gpointer *, gpointer *))test_method;
3900 F (&a1, &a2, &a3, &a4, &a5, &a6, &a7, &ex);
3901 if (!ex) {
3902 ret = 4;
3903 goto done;
3906 break;
3909 case 10: {
3910 /* thunks.cs:Test.Test10 */
3911 void (STDCALL *F)(gpointer*, gpointer*);
3913 gpointer obj1, obj2;
3915 obj1 = obj2 = CreateObject (&ex);
3916 if (ex) {
3917 ret = 4;
3918 goto done;
3921 F = (void (STDCALL *)(gpointer *, gpointer *))test_method;
3923 F (&obj1, &ex);
3924 if (ex) {
3925 ret = 5;
3926 goto done;
3929 if (obj1 == obj2) {
3930 ret = 6;
3931 goto done;
3934 break;
3937 case 100: {
3938 /* thunks.cs:TestStruct.Test0 */
3939 int (STDCALL *F)(gpointer*, gpointer*);
3941 gpointer obj;
3942 TestStruct *a1;
3943 int res;
3945 obj = CreateObject (&ex);
3946 if (ex) {
3947 ret = 4;
3948 goto done;
3951 if (!obj) {
3952 ret = 5;
3953 goto done;
3956 a1 = (TestStruct *)mono_object_unbox (obj);
3957 if (!a1) {
3958 ret = 6;
3959 goto done;
3962 a1->A = 42;
3963 a1->B = 3.1415;
3965 F = (int (STDCALL *)(gpointer *, gpointer *))test_method;
3967 res = F ((gpointer *)obj, &ex);
3968 if (ex) {
3969 ret = 7;
3970 goto done;
3973 if (!res) {
3974 ret = 8;
3975 goto done;
3978 /* check whether the call was really by value */
3979 if (a1->A != 42 || a1->B != 3.1415) {
3980 ret = 9;
3981 goto done;
3984 break;
3987 case 101: {
3988 /* thunks.cs:TestStruct.Test1 */
3989 void (STDCALL *F)(gpointer, gpointer*);
3991 TestStruct *a1;
3992 gpointer obj;
3994 obj = CreateObject (&ex);
3995 if (ex) {
3996 ret = 4;
3997 goto done;
4000 if (!obj) {
4001 ret = 5;
4002 goto done;
4005 a1 = (TestStruct *)mono_object_unbox (obj);
4006 if (!a1) {
4007 ret = 6;
4008 goto done;
4011 F = (void (STDCALL *)(gpointer, gpointer *))test_method;
4013 F (obj, &ex);
4014 if (ex) {
4015 ret = 7;
4016 goto done;
4019 if (a1->A != 42) {
4020 ret = 8;
4021 goto done;
4024 if (!(fabs (a1->B - 3.1415) < 0.001)) {
4025 ret = 9;
4026 goto done;
4029 break;
4032 case 102: {
4033 /* thunks.cs:TestStruct.Test2 */
4034 gpointer (STDCALL *F)(gpointer*);
4036 TestStruct *a1;
4037 gpointer obj;
4039 F = (gpointer (STDCALL *)(gpointer *))test_method;
4041 obj = F (&ex);
4042 if (ex) {
4043 ret = 4;
4044 goto done;
4047 if (!obj) {
4048 ret = 5;
4049 goto done;
4052 a1 = (TestStruct *)mono_object_unbox (obj);
4054 if (a1->A != 42) {
4055 ret = 5;
4056 goto done;
4059 if (!(fabs (a1->B - 3.1415) < 0.001)) {
4060 ret = 6;
4061 goto done;
4064 break;
4067 case 103: {
4068 /* thunks.cs:TestStruct.Test3 */
4069 void (STDCALL *F)(gpointer, gpointer*);
4071 TestStruct *a1;
4072 gpointer obj;
4074 obj = CreateObject (&ex);
4075 if (ex) {
4076 ret = 4;
4077 goto done;
4080 if (!obj) {
4081 ret = 5;
4082 goto done;
4085 a1 = (TestStruct *)mono_object_unbox (obj);
4087 if (!a1) {
4088 ret = 6;
4089 goto done;
4092 a1->A = 42;
4093 a1->B = 3.1415;
4095 F = (void (STDCALL *)(gpointer, gpointer *))test_method;
4097 F (obj, &ex);
4098 if (ex) {
4099 ret = 4;
4100 goto done;
4103 if (a1->A != 1) {
4104 ret = 5;
4105 goto done;
4108 if (a1->B != 17) {
4109 ret = 6;
4110 goto done;
4113 break;
4116 default:
4117 ret = 9;
4120 done:
4121 MONO_END_EFRAME;
4123 return ret;
4126 typedef struct
4128 char a;
4129 } winx64_struct1;
4131 LIBTEST_API int STDCALL
4132 mono_test_Winx64_struct1_in (winx64_struct1 var)
4134 if (var.a != 123)
4135 return 1;
4136 return 0;
4139 typedef struct
4141 char a;
4142 char b;
4143 } winx64_struct2;
4145 LIBTEST_API int STDCALL
4146 mono_test_Winx64_struct2_in (winx64_struct2 var)
4148 if (var.a != 4)
4149 return 1;
4150 if (var.b != 5)
4151 return 2;
4152 return 0;
4156 typedef struct
4158 char a;
4159 char b;
4160 short c;
4161 } winx64_struct3;
4163 LIBTEST_API int STDCALL
4164 mono_test_Winx64_struct3_in (winx64_struct3 var)
4166 if (var.a != 4)
4167 return 1;
4168 if (var.b != 5)
4169 return 2;
4170 if (var.c != 0x1234)
4171 return 3;
4172 return 0;
4175 typedef struct
4177 char a;
4178 char b;
4179 short c;
4180 unsigned int d;
4181 } winx64_struct4;
4183 LIBTEST_API int STDCALL
4184 mono_test_Winx64_struct4_in (winx64_struct4 var)
4186 if (var.a != 4)
4187 return 1;
4188 if (var.b != 5)
4189 return 2;
4190 if (var.c != 0x1234)
4191 return 3;
4192 if (var.d != 0x87654321)
4193 return 4;
4194 return 0;
4197 typedef struct
4199 char a;
4200 char b;
4201 char c;
4202 } winx64_struct5;
4204 LIBTEST_API int STDCALL
4205 mono_test_Winx64_struct5_in (winx64_struct5 var)
4207 if (var.a != 4)
4208 return 1;
4209 if (var.b != 5)
4210 return 2;
4211 if (var.c != 6)
4212 return 3;
4213 return 0;
4216 typedef struct
4218 winx64_struct1 a;
4219 short b;
4220 char c;
4221 } winx64_struct6;
4223 LIBTEST_API int STDCALL
4224 mono_test_Winx64_struct6_in (winx64_struct6 var)
4226 if (var.a.a != 4)
4227 return 1;
4228 if (var.b != 5)
4229 return 2;
4230 if (var.c != 6)
4231 return 3;
4232 return 0;
4235 LIBTEST_API int STDCALL
4236 mono_test_Winx64_structs_in1 (winx64_struct1 var1,
4237 winx64_struct2 var2,
4238 winx64_struct3 var3,
4239 winx64_struct4 var4)
4241 if (var1.a != 123)
4242 return 1;
4244 if (var2.a != 4)
4245 return 2;
4246 if (var2.b != 5)
4247 return 3;
4249 if (var3.a != 4)
4250 return 4;
4251 if (var3.b != 5)
4252 return 2;
4253 if (var3.c != 0x1234)
4254 return 5;
4256 if (var4.a != 4)
4257 return 6;
4258 if (var4.b != 5)
4259 return 7;
4260 if (var4.c != 0x1234)
4261 return 8;
4262 if (var4.d != 0x87654321)
4263 return 9;
4264 return 0;
4267 LIBTEST_API int STDCALL
4268 mono_test_Winx64_structs_in2 (winx64_struct1 var1,
4269 winx64_struct1 var2,
4270 winx64_struct1 var3,
4271 winx64_struct1 var4,
4272 winx64_struct1 var5)
4274 if (var1.a != 1)
4275 return 1;
4276 if (var2.a != 2)
4277 return 2;
4278 if (var3.a != 3)
4279 return 3;
4280 if (var4.a != 4)
4281 return 4;
4282 if (var5.a != 5)
4283 return 5;
4285 return 0;
4288 LIBTEST_API int STDCALL
4289 mono_test_Winx64_structs_in3 (winx64_struct1 var1,
4290 winx64_struct5 var2,
4291 winx64_struct1 var3,
4292 winx64_struct5 var4,
4293 winx64_struct1 var5,
4294 winx64_struct5 var6)
4296 if (var1.a != 1)
4297 return 1;
4299 if (var2.a != 2)
4300 return 2;
4301 if (var2.b != 3)
4302 return 2;
4303 if (var2.c != 4)
4304 return 4;
4306 if (var3.a != 5)
4307 return 5;
4309 if (var4.a != 6)
4310 return 6;
4311 if (var4.b != 7)
4312 return 7;
4313 if (var4.c != 8)
4314 return 8;
4316 if (var5.a != 9)
4317 return 9;
4319 if (var6.a != 10)
4320 return 10;
4321 if (var6.b != 11)
4322 return 11;
4323 if (var6.c != 12)
4324 return 12;
4326 return 0;
4329 LIBTEST_API winx64_struct1 STDCALL
4330 mono_test_Winx64_struct1_ret (void)
4332 winx64_struct1 ret;
4333 ret.a = 123;
4334 return ret;
4337 LIBTEST_API winx64_struct2 STDCALL
4338 mono_test_Winx64_struct2_ret (void)
4340 winx64_struct2 ret;
4341 ret.a = 4;
4342 ret.b = 5;
4343 return ret;
4346 LIBTEST_API winx64_struct3 STDCALL
4347 mono_test_Winx64_struct3_ret (void)
4349 winx64_struct3 ret;
4350 ret.a = 4;
4351 ret.b = 5;
4352 ret.c = 0x1234;
4353 return ret;
4356 LIBTEST_API winx64_struct4 STDCALL
4357 mono_test_Winx64_struct4_ret (void)
4359 winx64_struct4 ret;
4360 ret.a = 4;
4361 ret.b = 5;
4362 ret.c = 0x1234;
4363 ret.d = 0x87654321;
4364 return ret;
4367 LIBTEST_API winx64_struct5 STDCALL
4368 mono_test_Winx64_struct5_ret (void)
4370 winx64_struct5 ret;
4371 ret.a = 4;
4372 ret.b = 5;
4373 ret.c = 6;
4374 return ret;
4377 LIBTEST_API winx64_struct1 STDCALL
4378 mono_test_Winx64_struct1_ret_5_args (char a, char b, char c, char d, char e)
4380 winx64_struct1 ret;
4381 ret.a = a + b + c + d + e;
4382 return ret;
4385 LIBTEST_API winx64_struct5 STDCALL
4386 mono_test_Winx64_struct5_ret6_args (char a, char b, char c, char d, char e)
4388 winx64_struct5 ret;
4389 ret.a = a + b;
4390 ret.b = c + d;
4391 ret.c = e;
4392 return ret;
4395 typedef struct
4397 float a;
4398 float b;
4399 } winx64_floatStruct;
4401 LIBTEST_API int STDCALL
4402 mono_test_Winx64_floatStruct (winx64_floatStruct a)
4404 if (a.a > 5.6 || a.a < 5.4)
4405 return 1;
4407 if (a.b > 9.6 || a.b < 9.4)
4408 return 2;
4410 return 0;
4413 typedef struct
4415 double a;
4416 } winx64_doubleStruct;
4418 LIBTEST_API int STDCALL
4419 mono_test_Winx64_doubleStruct (winx64_doubleStruct a)
4421 if (a.a > 5.6 || a.a < 5.4)
4422 return 1;
4424 return 0;
4427 typedef int (STDCALL *managed_struct1_delegate) (winx64_struct1 a);
4429 LIBTEST_API int STDCALL
4430 mono_test_managed_Winx64_struct1_in(managed_struct1_delegate func)
4432 winx64_struct1 val;
4433 val.a = 5;
4434 return func (val);
4437 typedef int (STDCALL *managed_struct5_delegate) (winx64_struct5 a);
4439 LIBTEST_API int STDCALL
4440 mono_test_managed_Winx64_struct5_in(managed_struct5_delegate func)
4442 winx64_struct5 val;
4443 val.a = 5;
4444 val.b = 0x10;
4445 val.c = 0x99;
4446 return func (val);
4449 typedef int (STDCALL *managed_struct1_struct5_delegate) (winx64_struct1 a, winx64_struct5 b,
4450 winx64_struct1 c, winx64_struct5 d,
4451 winx64_struct1 e, winx64_struct5 f);
4453 LIBTEST_API int STDCALL
4454 mono_test_managed_Winx64_struct1_struct5_in(managed_struct1_struct5_delegate func)
4456 winx64_struct1 a, c, e;
4457 winx64_struct5 b, d, f;
4458 a.a = 1;
4459 b.a = 2; b.b = 3; b.c = 4;
4460 c.a = 5;
4461 d.a = 6; d.b = 7; d.c = 8;
4462 e.a = 9;
4463 f.a = 10; f.b = 11; f.c = 12;
4465 return func (a, b, c, d, e, f);
4468 typedef winx64_struct1 (STDCALL *managed_struct1_ret_delegate) (void);
4470 LIBTEST_API int STDCALL
4471 mono_test_Winx64_struct1_ret_managed (managed_struct1_ret_delegate func)
4473 winx64_struct1 ret;
4475 ret = func ();
4477 if (ret.a != 0x45)
4478 return 1;
4480 return 0;
4483 typedef winx64_struct5 (STDCALL *managed_struct5_ret_delegate) (void);
4485 LIBTEST_API int STDCALL
4486 mono_test_Winx64_struct5_ret_managed (managed_struct5_ret_delegate func)
4488 winx64_struct5 ret;
4490 ret = func ();
4492 if (ret.a != 0x12)
4493 return 1;
4494 if (ret.b != 0x34)
4495 return 2;
4496 if (ret.c != 0x56)
4497 return 3;
4499 return 0;
4502 LIBTEST_API int STDCALL
4503 mono_test_marshal_bool_in (int arg, unsigned int expected, unsigned int bDefaultMarsh, unsigned int bBoolCustMarsh,
4504 char bI1CustMarsh, unsigned char bU1CustMarsh, short bVBCustMarsh)
4506 switch (arg) {
4507 case 1:
4508 if (bDefaultMarsh != expected)
4509 return 1;
4510 break;
4511 case 2:
4512 if (bBoolCustMarsh != expected)
4513 return 2;
4514 break;
4515 case 3:
4516 if (bI1CustMarsh != expected)
4517 return 3;
4518 break;
4519 case 4:
4520 if (bU1CustMarsh != expected)
4521 return 4;
4522 break;
4523 case 5:
4524 if (bVBCustMarsh != expected)
4525 return 5;
4526 break;
4527 default:
4528 return 999;
4530 return 0;
4533 LIBTEST_API int STDCALL
4534 mono_test_marshal_bool_out (int arg, unsigned int testVal, unsigned int* bDefaultMarsh, unsigned int* bBoolCustMarsh,
4535 char* bI1CustMarsh, unsigned char* bU1CustMarsh, unsigned short* bVBCustMarsh)
4537 switch (arg) {
4538 case 1:
4539 if (!bDefaultMarsh)
4540 return 1;
4541 *bDefaultMarsh = testVal;
4542 break;
4543 case 2:
4544 if (!bBoolCustMarsh)
4545 return 2;
4546 *bBoolCustMarsh = testVal;
4547 break;
4548 case 3:
4549 if (!bI1CustMarsh)
4550 return 3;
4551 *bI1CustMarsh = (char)testVal;
4552 break;
4553 case 4:
4554 if (!bU1CustMarsh)
4555 return 4;
4556 *bU1CustMarsh = (unsigned char)testVal;
4557 break;
4558 case 5:
4559 if (!bVBCustMarsh)
4560 return 5;
4561 *bVBCustMarsh = (unsigned short)testVal;
4562 break;
4563 default:
4564 return 999;
4566 return 0;
4569 LIBTEST_API int STDCALL
4570 mono_test_marshal_bool_ref (int arg, unsigned int expected, unsigned int testVal, unsigned int* bDefaultMarsh,
4571 unsigned int* bBoolCustMarsh, char* bI1CustMarsh, unsigned char* bU1CustMarsh,
4572 unsigned short* bVBCustMarsh)
4574 switch (arg) {
4575 case 1:
4576 if (!bDefaultMarsh)
4577 return 1;
4578 if (*bDefaultMarsh != expected)
4579 return 2;
4580 *bDefaultMarsh = testVal;
4581 break;
4582 case 2:
4583 if (!bBoolCustMarsh)
4584 return 3;
4585 if (*bBoolCustMarsh != expected)
4586 return 4;
4587 *bBoolCustMarsh = testVal;
4588 break;
4589 case 3:
4590 if (!bI1CustMarsh)
4591 return 5;
4592 if (*bI1CustMarsh != expected)
4593 return 6;
4594 *bI1CustMarsh = (char)testVal;
4595 break;
4596 case 4:
4597 if (!bU1CustMarsh)
4598 return 7;
4599 if (*bU1CustMarsh != expected)
4600 return 8;
4601 *bU1CustMarsh = (unsigned char)testVal;
4602 break;
4603 case 5:
4604 if (!bVBCustMarsh)
4605 return 9;
4606 if (*bVBCustMarsh != expected)
4607 return 10;
4608 *bVBCustMarsh = (unsigned short)testVal;
4609 break;
4610 default:
4611 return 999;
4613 return 0;
4617 typedef int (STDCALL *MarshalBoolInDelegate) (int arg, unsigned int expected, unsigned int bDefaultMarsh,
4618 unsigned int bBoolCustMarsh, char bI1CustMarsh, unsigned char bU1CustMarsh, unsigned short bVBCustMarsh);
4620 LIBTEST_API int STDCALL
4621 mono_test_managed_marshal_bool_in (int arg, unsigned int expected, unsigned int testVal, MarshalBoolInDelegate pfcn)
4623 if (!pfcn)
4624 return 0x9900;
4626 switch (arg) {
4627 case 1:
4628 return pfcn (arg, expected, testVal, 0, 0, 0, 0);
4629 case 2:
4630 return pfcn (arg, expected, 0, testVal, 0, 0, 0);
4631 case 3:
4632 return pfcn (arg, expected, 0, 0, testVal, 0, 0);
4633 case 4:
4634 return pfcn (arg, expected, 0, 0, 0, testVal, 0);
4635 case 5:
4636 return pfcn (arg, expected, 0, 0, 0, 0, testVal);
4637 default:
4638 return 0x9800;
4641 return 0;
4644 typedef int (STDCALL *MarshalBoolOutDelegate) (int arg, unsigned int expected, unsigned int* bDefaultMarsh,
4645 unsigned int* bBoolCustMarsh, char* bI1CustMarsh, unsigned char* bU1CustMarsh, unsigned short* bVBCustMarsh);
4647 LIBTEST_API int STDCALL
4648 mono_test_managed_marshal_bool_out (int arg, unsigned int expected, unsigned int testVal, MarshalBoolOutDelegate pfcn)
4650 int ret;
4651 unsigned int lDefaultMarsh, lBoolCustMarsh;
4652 char lI1CustMarsh = 0;
4653 unsigned char lU1CustMarsh = 0;
4654 unsigned short lVBCustMarsh = 0;
4655 lDefaultMarsh = lBoolCustMarsh = 0;
4657 if (!pfcn)
4658 return 0x9900;
4660 switch (arg) {
4661 case 1: {
4662 unsigned int ltVal = 0;
4663 ret = pfcn (arg, testVal, &ltVal, &lBoolCustMarsh, &lI1CustMarsh, &lU1CustMarsh, &lVBCustMarsh);
4664 if (ret)
4665 return 0x0100 + ret;
4666 if (expected != ltVal)
4667 return 0x0200;
4668 break;
4670 case 2: {
4671 unsigned int ltVal = 0;
4672 ret = pfcn (arg, testVal, &lDefaultMarsh, &ltVal, &lI1CustMarsh, &lU1CustMarsh, &lVBCustMarsh);
4673 if (ret)
4674 return 0x0300 + ret;
4675 if (expected != ltVal)
4676 return 0x0400;
4677 break;
4679 case 3: {
4680 char ltVal = 0;
4681 ret = pfcn (arg, testVal, &lDefaultMarsh, &lBoolCustMarsh, &ltVal, &lU1CustMarsh, &lVBCustMarsh);
4682 if (ret)
4683 return 0x0500 + ret;
4684 if (expected != ltVal)
4685 return 0x0600;
4686 break;
4688 case 4: {
4689 unsigned char ltVal = 0;
4690 ret = pfcn (arg, testVal, &lDefaultMarsh, &lBoolCustMarsh, &lI1CustMarsh, &ltVal, &lVBCustMarsh);
4691 if (ret)
4692 return 0x0700 + ret;
4693 if (expected != ltVal)
4694 return 0x0800;
4695 break;
4697 case 5: {
4698 unsigned short ltVal = 0;
4699 ret = pfcn (arg, testVal, &lDefaultMarsh, &lBoolCustMarsh, &lI1CustMarsh, &lU1CustMarsh, &ltVal);
4700 if (ret)
4701 return 0x0900 + ret;
4702 if (expected != ltVal)
4703 return 0x1000;
4704 break;
4706 default:
4707 return 0x9800;
4710 return 0;
4713 typedef int (STDCALL *MarshalBoolRefDelegate) (int arg, unsigned int expected, unsigned int testVal, unsigned int* bDefaultMarsh,
4714 unsigned int* bBoolCustMarsh, char* bI1CustMarsh, unsigned char* bU1CustMarsh, unsigned short* bVBCustMarsh);
4716 LIBTEST_API int STDCALL
4717 mono_test_managed_marshal_bool_ref (int arg, unsigned int expected, unsigned int testVal, unsigned int outExpected,
4718 unsigned int outTestVal, MarshalBoolRefDelegate pfcn)
4720 int ret;
4721 unsigned int lDefaultMarsh, lBoolCustMarsh;
4722 char lI1CustMarsh = 0;
4723 unsigned char lU1CustMarsh = 0;
4724 unsigned short lVBCustMarsh = 0;
4725 lDefaultMarsh = lBoolCustMarsh = 0;
4727 if (!pfcn)
4728 return 0x9900;
4730 switch (arg) {
4731 case 1:
4733 unsigned int ltestVal = testVal;
4734 ret = pfcn (arg, expected, outTestVal, &ltestVal, &lBoolCustMarsh, &lI1CustMarsh, &lU1CustMarsh, &lVBCustMarsh);
4735 if (ret)
4736 return 0x0100 + ret;
4737 if (outExpected != ltestVal)
4738 return 0x0200;
4739 break;
4741 case 2:
4743 unsigned int ltestVal = testVal;
4744 ret = pfcn (arg, expected, outTestVal, &lDefaultMarsh, &ltestVal, &lI1CustMarsh, &lU1CustMarsh, &lVBCustMarsh);
4745 if (ret)
4746 return 0x0300 + ret;
4747 if (outExpected != ltestVal)
4748 return 0x0400;
4749 break;
4751 case 3:
4753 char ltestVal = testVal;
4754 ret = pfcn (arg, expected, outTestVal, &lDefaultMarsh, &lBoolCustMarsh, &ltestVal, &lU1CustMarsh, &lVBCustMarsh);
4755 if (ret)
4756 return 0x0500 + ret;
4757 if (outExpected != ltestVal)
4758 return 0x0600;
4759 break;
4761 case 4:
4763 unsigned char ltestVal = testVal;
4764 ret = pfcn (arg, expected, outTestVal, &lDefaultMarsh, &lBoolCustMarsh, &lI1CustMarsh, &ltestVal, &lVBCustMarsh);
4765 if (ret)
4766 return 0x0700 + ret;
4767 if (outExpected != ltestVal)
4768 return 0x0800;
4769 break;
4771 case 5:
4773 unsigned short ltestVal = testVal;
4774 ret = pfcn (arg, expected, outTestVal, &lDefaultMarsh, &lBoolCustMarsh, &lI1CustMarsh, &lU1CustMarsh, &ltestVal);
4775 if (ret)
4776 return 0x0900 + ret;
4777 if (outExpected != ltestVal)
4778 return 0x1000;
4779 break;
4781 default:
4782 return 0x9800;
4785 return 0;
4788 #ifdef WIN32
4790 LIBTEST_API int STDCALL
4791 mono_test_marshal_safearray_out_1dim_vt_bstr_empty (SAFEARRAY** safearray)
4793 /* Create an empty one-dimensional array of variants */
4794 SAFEARRAY *pSA;
4795 SAFEARRAYBOUND dimensions [1];
4797 dimensions [0].lLbound = 0;
4798 dimensions [0].cElements = 0;
4800 pSA= SafeArrayCreate (VT_VARIANT, 1, dimensions);
4801 *safearray = pSA;
4802 return S_OK;
4805 LIBTEST_API int STDCALL
4806 mono_test_marshal_safearray_out_1dim_vt_bstr (SAFEARRAY** safearray)
4808 /* Create a one-dimensional array of 10 variants filled with "0" to "9" */
4809 SAFEARRAY *pSA;
4810 SAFEARRAYBOUND dimensions [1];
4811 long i;
4812 gchar buffer [20];
4813 HRESULT hr = S_OK;
4814 long indices [1];
4816 dimensions [0].lLbound = 0;
4817 dimensions [0].cElements = 10;
4819 pSA= SafeArrayCreate (VT_VARIANT, 1, dimensions);
4820 for (i= dimensions [0].lLbound; i< (dimensions [0].cElements + dimensions [0].lLbound); i++) {
4821 VARIANT vOut;
4822 VariantInit (&vOut);
4823 vOut.vt = VT_BSTR;
4824 _ltoa (i,buffer,10);
4825 vOut.bstrVal= marshal_bstr_alloc (buffer);
4826 indices [0] = i;
4827 if ((hr = SafeArrayPutElement (pSA, indices, &vOut)) != S_OK) {
4828 VariantClear (&vOut);
4829 SafeArrayDestroy (pSA);
4830 return hr;
4832 VariantClear (&vOut);
4834 *safearray = pSA;
4835 return hr;
4838 LIBTEST_API int STDCALL
4839 mono_test_marshal_safearray_out_2dim_vt_i4 (SAFEARRAY** safearray)
4841 /* Create a two-dimensional array of 4x3 variants filled with 11, 12, 13, etc. */
4842 SAFEARRAY *pSA;
4843 SAFEARRAYBOUND dimensions [2];
4844 long i, j;
4845 HRESULT hr = S_OK;
4846 long indices [2];
4848 dimensions [0].lLbound = 0;
4849 dimensions [0].cElements = 4;
4850 dimensions [1].lLbound = 0;
4851 dimensions [1].cElements = 3;
4853 pSA= SafeArrayCreate(VT_VARIANT, 2, dimensions);
4854 for (i= dimensions [0].lLbound; i< (dimensions [0].cElements + dimensions [0].lLbound); i++) {
4855 for (j= dimensions [1].lLbound; j< (dimensions [1].cElements + dimensions [1].lLbound); j++) {
4856 VARIANT vOut;
4857 VariantInit (&vOut);
4858 vOut.vt = VT_I4;
4859 vOut.lVal = (i+1)*10+(j+1);
4860 indices [0] = i;
4861 indices [1] = j;
4862 if ((hr = SafeArrayPutElement (pSA, indices, &vOut)) != S_OK) {
4863 VariantClear (&vOut);
4864 SafeArrayDestroy (pSA);
4865 return hr;
4867 VariantClear (&vOut); // does a deep destroy of source VARIANT
4870 *safearray = pSA;
4871 return hr;
4874 LIBTEST_API int STDCALL
4875 mono_test_marshal_safearray_out_4dim_vt_i4 (SAFEARRAY** safearray)
4877 /* Create a four-dimensional array of 10x3x6x7 variants filled with their indices */
4878 /* Also use non zero lower bounds */
4879 SAFEARRAY *pSA;
4880 SAFEARRAYBOUND dimensions [4];
4881 long i;
4882 HRESULT hr = S_OK;
4883 VARIANT *pData;
4885 dimensions [0].lLbound = 15;
4886 dimensions [0].cElements = 10;
4887 dimensions [1].lLbound = 20;
4888 dimensions [1].cElements = 3;
4889 dimensions [2].lLbound = 5;
4890 dimensions [2].cElements = 6;
4891 dimensions [3].lLbound = 12;
4892 dimensions [3].cElements = 7;
4894 pSA= SafeArrayCreate (VT_VARIANT, 4, dimensions);
4896 SafeArrayAccessData (pSA, (void **)&pData);
4898 for (i= 0; i< 10*3*6*7; i++) {
4899 VariantInit(&pData [i]);
4900 pData [i].vt = VT_I4;
4901 pData [i].lVal = i;
4903 SafeArrayUnaccessData (pSA);
4904 *safearray = pSA;
4905 return hr;
4908 LIBTEST_API int STDCALL
4909 mono_test_marshal_safearray_in_byval_1dim_empty (SAFEARRAY* safearray)
4911 /* Check that array is one dimensional and empty */
4913 UINT dim;
4914 long lbound, ubound;
4916 dim = SafeArrayGetDim (safearray);
4917 if (dim != 1)
4918 return 1;
4920 SafeArrayGetLBound (safearray, 1, &lbound);
4921 SafeArrayGetUBound (safearray, 1, &ubound);
4923 if ((lbound > 0) || (ubound > 0))
4924 return 1;
4926 return 0;
4929 LIBTEST_API int STDCALL
4930 mono_test_marshal_safearray_in_byval_1dim_vt_i4 (SAFEARRAY* safearray)
4932 /* Check that array is one dimensional containing integers from 1 to 10 */
4934 UINT dim;
4935 long lbound, ubound;
4936 VARIANT *pData;
4937 long i;
4938 int result=0;
4940 dim = SafeArrayGetDim (safearray);
4941 if (dim != 1)
4942 return 1;
4944 SafeArrayGetLBound (safearray, 1, &lbound);
4945 SafeArrayGetUBound (safearray, 1, &ubound);
4947 if ((lbound != 0) || (ubound != 9))
4948 return 1;
4950 SafeArrayAccessData (safearray, (void **)&pData);
4951 for (i= lbound; i <= ubound; i++) {
4952 if ((VariantChangeType (&pData [i], &pData [i], VARIANT_NOUSEROVERRIDE, VT_I4) != S_OK) || (pData [i].lVal != i + 1))
4953 result = 1;
4955 SafeArrayUnaccessData (safearray);
4957 return result;
4960 LIBTEST_API int STDCALL
4961 mono_test_marshal_safearray_in_byval_1dim_vt_mixed (SAFEARRAY* safearray)
4963 /* Check that array is one dimensional containing integers mixed with strings from 0 to 12 */
4965 UINT dim;
4966 long lbound, ubound;
4967 VARIANT *pData;
4968 long i;
4969 long indices [1];
4970 VARIANT element;
4971 int result=0;
4973 VariantInit (&element);
4975 dim = SafeArrayGetDim (safearray);
4976 if (dim != 1)
4977 return 1;
4979 SafeArrayGetLBound (safearray, 1, &lbound);
4980 SafeArrayGetUBound (safearray, 1, &ubound);
4982 if ((lbound != 0) || (ubound != 12))
4983 return 1;
4985 SafeArrayAccessData (safearray, (void **)&pData);
4986 for (i= lbound; i <= ubound; i++) {
4987 if ((i%2 == 0) && (pData [i].vt != VT_I4))
4988 result = 1;
4989 if ((i%2 == 1) && (pData [i].vt != VT_BSTR))
4990 result = 1;
4991 if ((VariantChangeType (&pData [i], &pData [i], VARIANT_NOUSEROVERRIDE, VT_I4) != S_OK) || (pData [i].lVal != i))
4992 result = 1;
4994 SafeArrayUnaccessData (safearray);
4996 /* Change the first element of the array to verify that [in] parameters are not marshalled back to the managed side */
4998 indices [0] = 0;
4999 element.vt = VT_I4;
5000 element.lVal = 333;
5001 SafeArrayPutElement (safearray, indices, &element);
5002 VariantClear (&element);
5004 return result;
5007 LIBTEST_API int STDCALL
5008 mono_test_marshal_safearray_in_byval_2dim_vt_i4 (SAFEARRAY* safearray)
5010 /* Check that array is one dimensional containing integers mixed with strings from 0 to 12 */
5012 UINT dim;
5013 long lbound1, ubound1, lbound2, ubound2;
5014 long i, j, failed;
5015 long indices [2];
5016 VARIANT element;
5018 VariantInit (&element);
5020 dim = SafeArrayGetDim (safearray);
5021 if (dim != 2)
5022 return 1;
5024 SafeArrayGetLBound (safearray, 1, &lbound1);
5025 SafeArrayGetUBound (safearray, 1, &ubound1);
5027 if ((lbound1 != 0) || (ubound1 != 1))
5028 return 1;
5030 SafeArrayGetLBound (safearray, 2, &lbound2);
5031 SafeArrayGetUBound (safearray, 2, &ubound2);
5033 if ((lbound2 != 0) || (ubound2 != 3)) {
5034 return 1;
5037 for (i= lbound1; i <= ubound1; i++) {
5038 indices [0] = i;
5039 for (j= lbound2; j <= ubound2; j++) {
5040 indices [1] = j;
5041 if (SafeArrayGetElement (safearray, indices, &element) != S_OK)
5042 return 1;
5043 failed = ((element.vt != VT_I4) || (element.lVal != 10*(i+1)+(j+1)));
5044 VariantClear (&element);
5045 if (failed)
5046 return 1;
5050 /* Change the first element of the array to verify that [in] parameters are not marshalled back to the managed side */
5052 indices [0] = 0;
5053 indices [1] = 0;
5054 element.vt = VT_I4;
5055 element.lVal = 333;
5056 SafeArrayPutElement (safearray, indices, &element);
5057 VariantClear (&element);
5059 return 0;
5062 LIBTEST_API int STDCALL
5063 mono_test_marshal_safearray_in_byval_3dim_vt_bstr (SAFEARRAY* safearray)
5065 /* Check that array is one dimensional containing integers mixed with strings from 0 to 12 */
5067 UINT dim;
5068 long lbound1, ubound1, lbound2, ubound2, lbound3, ubound3;
5069 long i, j, k, failed;
5070 long indices [3];
5071 VARIANT element;
5073 VariantInit (&element);
5075 dim = SafeArrayGetDim (safearray);
5076 if (dim != 3)
5077 return 1;
5079 SafeArrayGetLBound (safearray, 1, &lbound1);
5080 SafeArrayGetUBound (safearray, 1, &ubound1);
5082 if ((lbound1 != 0) || (ubound1 != 1))
5083 return 1;
5085 SafeArrayGetLBound (safearray, 2, &lbound2);
5086 SafeArrayGetUBound (safearray, 2, &ubound2);
5088 if ((lbound2 != 0) || (ubound2 != 1))
5089 return 1;
5091 SafeArrayGetLBound (safearray, 3, &lbound3);
5092 SafeArrayGetUBound (safearray, 3, &ubound3);
5094 if ((lbound3 != 0) || (ubound3 != 2))
5095 return 1;
5097 for (i= lbound1; i <= ubound1; i++) {
5098 indices [0] = i;
5099 for (j= lbound2; j <= ubound2; j++) {
5100 indices [1] = j;
5101 for (k= lbound3; k <= ubound3; k++) {
5102 indices [2] = k;
5103 if (SafeArrayGetElement (safearray, indices, &element) != S_OK)
5104 return 1;
5105 failed = ((element.vt != VT_BSTR)
5106 || (VariantChangeType (&element, &element, VARIANT_NOUSEROVERRIDE, VT_I4) != S_OK)
5107 || (element.lVal != 100*(i+1)+10*(j+1)+(k+1)));
5108 VariantClear (&element);
5109 if (failed)
5110 return 1;
5115 /* Change the first element of the array to verify that [in] parameters are not marshalled back to the managed side */
5117 indices [0] = 0;
5118 indices [1] = 0;
5119 indices [2] = 0;
5120 element.vt = VT_BSTR;
5121 element.bstrVal = SysAllocString(L"Should not be copied");
5122 SafeArrayPutElement (safearray, indices, &element);
5123 VariantClear (&element);
5125 return 0;
5128 LIBTEST_API int STDCALL
5129 mono_test_marshal_safearray_in_byref_3dim_vt_bstr (SAFEARRAY** safearray)
5131 return mono_test_marshal_safearray_in_byval_3dim_vt_bstr (*safearray);
5134 LIBTEST_API int STDCALL
5135 mono_test_marshal_safearray_in_out_byref_1dim_empty (SAFEARRAY** safearray)
5137 /* Check that the input array is what is expected and change it so the caller can check */
5138 /* correct marshalling back to managed code */
5140 UINT dim;
5141 long lbound, ubound;
5142 SAFEARRAYBOUND dimensions [1];
5143 long i;
5144 wchar_t buffer [20];
5145 HRESULT hr = S_OK;
5146 long indices [1];
5148 /* Check that in array is one dimensional and empty */
5150 dim = SafeArrayGetDim (*safearray);
5151 if (dim != 1) {
5152 return 1;
5155 SafeArrayGetLBound (*safearray, 1, &lbound);
5156 SafeArrayGetUBound (*safearray, 1, &ubound);
5158 if ((lbound > 0) || (ubound > 0)) {
5159 return 1;
5162 /* Re-dimension the array and return a one-dimensional array of 8 variants filled with "0" to "7" */
5164 dimensions [0].lLbound = 0;
5165 dimensions [0].cElements = 8;
5167 hr = SafeArrayRedim (*safearray, dimensions);
5168 if (hr != S_OK)
5169 return 1;
5171 for (i= dimensions [0].lLbound; i< (dimensions [0].lLbound + dimensions [0].cElements); i++) {
5172 VARIANT vOut;
5173 VariantInit (&vOut);
5174 vOut.vt = VT_BSTR;
5175 _ltow (i,buffer,10);
5176 vOut.bstrVal = SysAllocString (buffer);
5177 indices [0] = i;
5178 if ((hr = SafeArrayPutElement (*safearray, indices, &vOut)) != S_OK) {
5179 VariantClear (&vOut);
5180 SafeArrayDestroy (*safearray);
5181 return hr;
5183 VariantClear (&vOut);
5185 return hr;
5188 LIBTEST_API int STDCALL
5189 mono_test_marshal_safearray_in_out_byref_3dim_vt_bstr (SAFEARRAY** safearray)
5191 /* Check that the input array is what is expected and change it so the caller can check */
5192 /* correct marshalling back to managed code */
5194 UINT dim;
5195 long lbound1, ubound1, lbound2, ubound2, lbound3, ubound3;
5196 SAFEARRAYBOUND dimensions [1];
5197 long i, j, k, failed;
5198 wchar_t buffer [20];
5199 HRESULT hr = S_OK;
5200 long indices [3];
5201 VARIANT element;
5203 VariantInit (&element);
5205 /* Check that in array is three dimensional and contains the expected values */
5207 dim = SafeArrayGetDim (*safearray);
5208 if (dim != 3)
5209 return 1;
5211 SafeArrayGetLBound (*safearray, 1, &lbound1);
5212 SafeArrayGetUBound (*safearray, 1, &ubound1);
5214 if ((lbound1 != 0) || (ubound1 != 1))
5215 return 1;
5217 SafeArrayGetLBound (*safearray, 2, &lbound2);
5218 SafeArrayGetUBound (*safearray, 2, &ubound2);
5220 if ((lbound2 != 0) || (ubound2 != 1))
5221 return 1;
5223 SafeArrayGetLBound (*safearray, 3, &lbound3);
5224 SafeArrayGetUBound (*safearray, 3, &ubound3);
5226 if ((lbound3 != 0) || (ubound3 != 2))
5227 return 1;
5229 for (i= lbound1; i <= ubound1; i++) {
5230 indices [0] = i;
5231 for (j= lbound2; j <= ubound2; j++) {
5232 indices [1] = j;
5233 for (k= lbound3; k <= ubound3; k++) {
5234 indices [2] = k;
5235 if (SafeArrayGetElement (*safearray, indices, &element) != S_OK)
5236 return 1;
5237 failed = ((element.vt != VT_BSTR)
5238 || (VariantChangeType (&element, &element, VARIANT_NOUSEROVERRIDE, VT_I4) != S_OK)
5239 || (element.lVal != 100*(i+1)+10*(j+1)+(k+1)));
5240 VariantClear (&element);
5241 if (failed)
5242 return 1;
5247 hr = SafeArrayDestroy (*safearray);
5248 if (hr != S_OK)
5249 return 1;
5251 /* Return a new one-dimensional array of 8 variants filled with "0" to "7" */
5253 dimensions [0].lLbound = 0;
5254 dimensions [0].cElements = 8;
5256 *safearray = SafeArrayCreate (VT_VARIANT, 1, dimensions);
5258 for (i= dimensions [0].lLbound; i< (dimensions [0].lLbound + dimensions [0].cElements); i++) {
5259 VARIANT vOut;
5260 VariantInit (&vOut);
5261 vOut.vt = VT_BSTR;
5262 _ltow (i,buffer,10);
5263 vOut.bstrVal = SysAllocString (buffer);
5264 indices [0] = i;
5265 if ((hr = SafeArrayPutElement (*safearray, indices, &vOut)) != S_OK) {
5266 VariantClear (&vOut);
5267 SafeArrayDestroy (*safearray);
5268 return hr;
5270 VariantClear (&vOut);
5272 return hr;
5275 LIBTEST_API int STDCALL
5276 mono_test_marshal_safearray_in_out_byref_1dim_vt_i4 (SAFEARRAY** safearray)
5278 /* Check that the input array is what is expected and change it so the caller can check */
5279 /* correct marshalling back to managed code */
5281 UINT dim;
5282 long lbound1, ubound1;
5283 long i, failed;
5284 HRESULT hr = S_OK;
5285 long indices [1];
5286 VARIANT element;
5288 VariantInit (&element);
5290 /* Check that in array is one dimensional and contains the expected value */
5292 dim = SafeArrayGetDim (*safearray);
5293 if (dim != 1)
5294 return 1;
5296 SafeArrayGetLBound (*safearray, 1, &lbound1);
5297 SafeArrayGetUBound (*safearray, 1, &ubound1);
5299 ubound1 = 1;
5300 if ((lbound1 != 0) || (ubound1 != 1))
5301 return 1;
5302 ubound1 = 0;
5304 for (i= lbound1; i <= ubound1; i++) {
5305 indices [0] = i;
5306 if (SafeArrayGetElement (*safearray, indices, &element) != S_OK)
5307 return 1;
5308 failed = (element.vt != VT_I4) || (element.lVal != i+1);
5309 VariantClear (&element);
5310 if (failed)
5311 return 1;
5314 /* Change one of the elements of the array to verify that [out] parameter is marshalled back to the managed side */
5316 indices [0] = 0;
5317 element.vt = VT_I4;
5318 element.lVal = -1;
5319 SafeArrayPutElement (*safearray, indices, &element);
5320 VariantClear (&element);
5322 return hr;
5325 LIBTEST_API int STDCALL
5326 mono_test_marshal_safearray_in_out_byval_1dim_vt_i4 (SAFEARRAY* safearray)
5328 /* Check that the input array is what is expected and change it so the caller can check */
5329 /* correct marshalling back to managed code */
5331 UINT dim;
5332 long lbound1, ubound1;
5333 SAFEARRAYBOUND dimensions [1];
5334 long i, failed;
5335 HRESULT hr = S_OK;
5336 long indices [1];
5337 VARIANT element;
5339 VariantInit (&element);
5341 /* Check that in array is one dimensional and contains the expected value */
5343 dim = SafeArrayGetDim (safearray);
5344 if (dim != 1)
5345 return 1;
5347 SafeArrayGetLBound (safearray, 1, &lbound1);
5348 SafeArrayGetUBound (safearray, 1, &ubound1);
5350 if ((lbound1 != 0) || (ubound1 != 0))
5351 return 1;
5353 for (i= lbound1; i <= ubound1; i++) {
5354 indices [0] = i;
5355 if (SafeArrayGetElement (safearray, indices, &element) != S_OK)
5356 return 1;
5357 failed = (element.vt != VT_I4) || (element.lVal != i+1);
5358 VariantClear (&element);
5359 if (failed)
5360 return 1;
5363 /* Change the array to verify how [out] parameter is marshalled back to the managed side */
5365 /* Redimension the array */
5366 dimensions [0].lLbound = lbound1;
5367 dimensions [0].cElements = 2;
5368 hr = SafeArrayRedim(safearray, dimensions);
5370 indices [0] = 0;
5371 element.vt = VT_I4;
5372 element.lVal = 12345;
5373 SafeArrayPutElement (safearray, indices, &element);
5374 VariantClear (&element);
5376 indices [0] = 1;
5377 element.vt = VT_I4;
5378 element.lVal = -12345;
5379 SafeArrayPutElement (safearray, indices, &element);
5380 VariantClear (&element);
5382 return hr;
5385 LIBTEST_API int STDCALL
5386 mono_test_marshal_safearray_in_out_byval_3dim_vt_bstr (SAFEARRAY* safearray)
5388 /* Check that the input array is what is expected and change it so the caller can check */
5389 /* correct marshalling back to managed code */
5391 UINT dim;
5392 long lbound1, ubound1, lbound2, ubound2, lbound3, ubound3;
5393 long i, j, k, failed;
5394 HRESULT hr = S_OK;
5395 long indices [3];
5396 VARIANT element;
5398 VariantInit (&element);
5400 /* Check that in array is three dimensional and contains the expected values */
5402 dim = SafeArrayGetDim (safearray);
5403 if (dim != 3)
5404 return 1;
5406 SafeArrayGetLBound (safearray, 1, &lbound1);
5407 SafeArrayGetUBound (safearray, 1, &ubound1);
5409 if ((lbound1 != 0) || (ubound1 != 1))
5410 return 1;
5412 SafeArrayGetLBound (safearray, 2, &lbound2);
5413 SafeArrayGetUBound (safearray, 2, &ubound2);
5415 if ((lbound2 != 0) || (ubound2 != 1))
5416 return 1;
5418 SafeArrayGetLBound (safearray, 3, &lbound3);
5419 SafeArrayGetUBound (safearray, 3, &ubound3);
5421 if ((lbound3 != 0) || (ubound3 != 2))
5422 return 1;
5424 for (i= lbound1; i <= ubound1; i++) {
5425 indices [0] = i;
5426 for (j= lbound2; j <= ubound2; j++) {
5427 indices [1] = j;
5428 for (k= lbound3; k <= ubound3; k++) {
5429 indices [2] = k;
5430 if (SafeArrayGetElement (safearray, indices, &element) != S_OK)
5431 return 1;
5432 failed = ((element.vt != VT_BSTR)
5433 || (VariantChangeType (&element, &element, VARIANT_NOUSEROVERRIDE, VT_I4) != S_OK)
5434 || (element.lVal != 100*(i+1)+10*(j+1)+(k+1)));
5435 VariantClear (&element);
5436 if (failed)
5437 return 1;
5442 /* Change the elements of the array to verify that [out] parameter is marshalled back to the managed side */
5444 indices [0] = 1;
5445 indices [1] = 1;
5446 indices [2] = 2;
5447 element.vt = VT_I4;
5448 element.lVal = 333;
5449 SafeArrayPutElement (safearray, indices, &element);
5450 VariantClear (&element);
5452 indices [0] = 1;
5453 indices [1] = 1;
5454 indices [2] = 1;
5455 element.vt = VT_I4;
5456 element.lVal = 111;
5457 SafeArrayPutElement (safearray, indices, &element);
5458 VariantClear (&element);
5460 indices [0] = 0;
5461 indices [1] = 1;
5462 indices [2] = 0;
5463 element.vt = VT_BSTR;
5464 element.bstrVal = marshal_bstr_alloc("ABCDEFG");
5465 SafeArrayPutElement (safearray, indices, &element);
5466 VariantClear (&element);
5468 return hr;
5471 LIBTEST_API int STDCALL
5472 mono_test_marshal_safearray_mixed(
5473 SAFEARRAY *safearray1,
5474 SAFEARRAY **safearray2,
5475 SAFEARRAY *safearray3,
5476 SAFEARRAY **safearray4
5479 HRESULT hr = S_OK;
5481 /* Initialize out parameters */
5482 *safearray2 = NULL;
5484 /* array1: Check that in array is one dimensional and contains the expected value */
5485 hr = mono_test_marshal_safearray_in_out_byval_1dim_vt_i4 (safearray1);
5487 /* array2: Fill in with some values to check on the managed side */
5488 if (hr == S_OK)
5489 hr = mono_test_marshal_safearray_out_1dim_vt_bstr (safearray2);
5491 /* array3: Check that in array is one dimensional and contains the expected value */
5492 if (hr == S_OK)
5493 hr = mono_test_marshal_safearray_in_byval_1dim_vt_mixed(safearray3);
5495 /* array4: Check input values and fill in with some values to check on the managed side */
5496 if (hr == S_OK)
5497 hr = mono_test_marshal_safearray_in_out_byref_3dim_vt_bstr(safearray4);
5499 return hr;
5502 #endif
5504 static int call_managed_res;
5506 static void
5507 call_managed (gpointer arg)
5509 SimpleDelegate del = (SimpleDelegate)arg;
5511 call_managed_res = del (42);
5514 LIBTEST_API int STDCALL
5515 mono_test_marshal_thread_attach (SimpleDelegate del)
5517 #ifdef WIN32
5518 return 43;
5519 #else
5520 int res;
5521 pthread_t t;
5523 res = pthread_create (&t, NULL, (gpointer (*)(gpointer))call_managed, del);
5524 g_assert (res == 0);
5525 pthread_join (t, NULL);
5527 return call_managed_res;
5528 #endif
5531 typedef struct {
5532 char arr [4 * 1024];
5533 } LargeStruct;
5535 typedef int (STDCALL *LargeStructDelegate) (LargeStruct *s);
5537 static void
5538 call_managed_large_vt (gpointer arg)
5540 LargeStructDelegate del = (LargeStructDelegate)arg;
5541 LargeStruct s;
5543 call_managed_res = del (&s);
5546 LIBTEST_API int STDCALL
5547 mono_test_marshal_thread_attach_large_vt (SimpleDelegate del)
5549 #ifdef WIN32
5550 return 43;
5551 #else
5552 int res;
5553 pthread_t t;
5555 res = pthread_create (&t, NULL, (gpointer (*)(gpointer))call_managed_large_vt, del);
5556 g_assert (res == 0);
5557 pthread_join (t, NULL);
5559 return call_managed_res;
5560 #endif
5563 typedef int (STDCALL *Callback) (void);
5565 static Callback callback;
5567 LIBTEST_API void STDCALL
5568 mono_test_marshal_set_callback (Callback cb)
5570 callback = cb;
5573 LIBTEST_API int STDCALL
5574 mono_test_marshal_call_callback (void)
5576 return callback ();
5579 LIBTEST_API int STDCALL
5580 mono_test_marshal_lpstr (char *str)
5582 return strcmp ("ABC", str);
5585 LIBTEST_API int STDCALL
5586 mono_test_marshal_lpwstr (gunichar2 *str)
5588 char *s;
5589 int res;
5591 s = g_utf16_to_utf8 (str, -1, NULL, NULL, NULL);
5592 res = strcmp ("ABC", s);
5593 g_free (s);
5595 return res;
5598 LIBTEST_API char* STDCALL
5599 mono_test_marshal_return_lpstr (void)
5601 char *res = (char *)marshal_alloc (4);
5602 strcpy (res, "XYZ");
5603 return res;
5607 LIBTEST_API gunichar2* STDCALL
5608 mono_test_marshal_return_lpwstr (void)
5610 gunichar2 *res = (gunichar2 *)marshal_alloc (8);
5611 gunichar2* tmp = g_utf8_to_utf16 ("XYZ", -1, NULL, NULL, NULL);
5613 memcpy (res, tmp, 8);
5614 g_free (tmp);
5616 return res;
5619 typedef struct {
5620 double d;
5621 } SingleDoubleStruct;
5623 LIBTEST_API SingleDoubleStruct STDCALL
5624 mono_test_marshal_return_single_double_struct (void)
5626 SingleDoubleStruct res;
5628 res.d = 3.0;
5630 return res;
5634 #ifndef TARGET_X86
5636 LIBTEST_API int STDCALL
5637 mono_test_has_thiscall (void)
5639 return 1;
5642 LIBTEST_API int
5643 _mono_test_native_thiscall1 (int arg)
5645 return arg;
5648 LIBTEST_API int
5649 _mono_test_native_thiscall2 (int arg, int arg2)
5651 return arg + (arg2^1);
5654 LIBTEST_API int
5655 _mono_test_native_thiscall3 (int arg, int arg2, int arg3)
5657 return arg + (arg2^1) + (arg3^2);
5660 LIBTEST_API int STDCALL
5661 _mono_test_managed_thiscall1 (int (*fn)(int), int arg)
5663 return fn(arg);
5666 LIBTEST_API int STDCALL
5667 _mono_test_managed_thiscall2 (int (*fn)(int,int), int arg, int arg2)
5669 return fn(arg, arg2);
5672 LIBTEST_API int STDCALL
5673 _mono_test_managed_thiscall3 (int (*fn)(int,int,int), int arg, int arg2, int arg3)
5675 return fn(arg, arg2, arg3);
5678 #elif defined(__GNUC__)
5680 LIBTEST_API int STDCALL
5681 mono_test_has_thiscall (void)
5683 return 1;
5686 #define def_asm_fn(name) \
5687 "\t.align 4\n" \
5688 "\t.globl _" #name "\n" \
5689 "_" #name ":\n" \
5690 "\t.globl __" #name "\n" \
5691 "__" #name ":\n"
5693 asm(".text\n"
5695 def_asm_fn(mono_test_native_thiscall1)
5696 "\tmovl %ecx,%eax\n"
5697 "\tret\n"
5699 def_asm_fn(mono_test_native_thiscall2)
5700 "\tmovl %ecx,%eax\n"
5701 "\tmovl 4(%esp),%ecx\n"
5702 "\txorl $1,%ecx\n"
5703 "\taddl %ecx,%eax\n"
5704 "\tret $4\n"
5706 def_asm_fn(mono_test_native_thiscall3)
5707 "\tmovl %ecx,%eax\n"
5708 "\tmovl 4(%esp),%ecx\n"
5709 "\txorl $1,%ecx\n"
5710 "\taddl %ecx,%eax\n"
5711 "\tmovl 8(%esp),%ecx\n"
5712 "\txorl $2,%ecx\n"
5713 "\taddl %ecx,%eax\n"
5714 "\tret $8\n"
5716 def_asm_fn(mono_test_managed_thiscall1)
5717 "\tpopl %eax\n"
5718 "\tpopl %edx\n"
5719 "\tpopl %ecx\n"
5720 "\tpushl %eax\n"
5721 "\tjmp *%edx\n"
5723 def_asm_fn(mono_test_managed_thiscall2)
5724 "\tpopl %eax\n"
5725 "\tpopl %edx\n"
5726 "\tpopl %ecx\n"
5727 "\tpushl %eax\n"
5728 "\tjmp *%edx\n"
5730 def_asm_fn(mono_test_managed_thiscall3)
5731 "\tpopl %eax\n"
5732 "\tpopl %edx\n"
5733 "\tpopl %ecx\n"
5734 "\tpushl %eax\n"
5735 "\tjmp *%edx\n"
5739 #else
5741 LIBTEST_API int STDCALL
5742 mono_test_has_thiscall (void)
5744 return 0;
5747 #endif
5750 typedef struct {
5751 char f1;
5752 } sbyte1;
5754 LIBTEST_API sbyte1 STDCALL
5755 mono_return_sbyte1 (sbyte1 s1, int addend) {
5756 if (s1.f1 != 1) {
5757 fprintf(stderr, "mono_return_sbyte1 s1.f1: got %d but expected %d\n", s1.f1, 1);
5759 s1.f1+=addend;
5760 return s1;
5763 typedef struct {
5764 char f1,f2;
5765 } sbyte2;
5767 LIBTEST_API sbyte2 STDCALL
5768 mono_return_sbyte2 (sbyte2 s2, int addend) {
5769 if (s2.f1 != 1) {
5770 fprintf(stderr, "mono_return_sbyte2 s2.f1: got %d but expected %d\n", s2.f1, 1);
5772 if (s2.f2 != 2) {
5773 fprintf(stderr, "mono_return_sbyte2 s2.f2: got %d but expected %d\n", s2.f2, 2);
5775 s2.f1+=addend; s2.f2+=addend;
5776 return s2;
5779 typedef struct {
5780 char f1,f2,f3;
5781 } sbyte3;
5783 LIBTEST_API sbyte3 STDCALL
5784 mono_return_sbyte3 (sbyte3 s3, int addend) {
5785 if (s3.f1 != 1) {
5786 fprintf(stderr, "mono_return_sbyte3 s3.f1: got %d but expected %d\n", s3.f1, 1);
5788 if (s3.f2 != 2) {
5789 fprintf(stderr, "mono_return_sbyte3 s3.f2: got %d but expected %d\n", s3.f2, 2);
5791 if (s3.f3 != 3) {
5792 fprintf(stderr, "mono_return_sbyte3 s3.f3: got %d but expected %d\n", s3.f3, 3);
5794 s3.f1+=addend; s3.f2+=addend; s3.f3+=addend;
5795 return s3;
5798 typedef struct {
5799 char f1,f2,f3,f4;
5800 } sbyte4;
5802 LIBTEST_API sbyte4 STDCALL
5803 mono_return_sbyte4 (sbyte4 s4, int addend) {
5804 if (s4.f1 != 1) {
5805 fprintf(stderr, "mono_return_sbyte4 s4.f1: got %d but expected %d\n", s4.f1, 1);
5807 if (s4.f2 != 2) {
5808 fprintf(stderr, "mono_return_sbyte4 s4.f2: got %d but expected %d\n", s4.f2, 2);
5810 if (s4.f3 != 3) {
5811 fprintf(stderr, "mono_return_sbyte4 s4.f3: got %d but expected %d\n", s4.f3, 3);
5813 if (s4.f4 != 4) {
5814 fprintf(stderr, "mono_return_sbyte4 s4.f4: got %d but expected %d\n", s4.f4, 4);
5816 s4.f1+=addend; s4.f2+=addend; s4.f3+=addend; s4.f4+=addend;
5817 return s4;
5820 typedef struct {
5821 char f1,f2,f3,f4,f5;
5822 } sbyte5;
5824 LIBTEST_API sbyte5 STDCALL
5825 mono_return_sbyte5 (sbyte5 s5, int addend) {
5826 if (s5.f1 != 1) {
5827 fprintf(stderr, "mono_return_sbyte5 s5.f1: got %d but expected %d\n", s5.f1, 1);
5829 if (s5.f2 != 2) {
5830 fprintf(stderr, "mono_return_sbyte5 s5.f2: got %d but expected %d\n", s5.f2, 2);
5832 if (s5.f3 != 3) {
5833 fprintf(stderr, "mono_return_sbyte5 s5.f3: got %d but expected %d\n", s5.f3, 3);
5835 if (s5.f4 != 4) {
5836 fprintf(stderr, "mono_return_sbyte5 s5.f4: got %d but expected %d\n", s5.f4, 4);
5838 if (s5.f5 != 5) {
5839 fprintf(stderr, "mono_return_sbyte5 s5.f5: got %d but expected %d\n", s5.f5, 5);
5841 s5.f1+=addend; s5.f2+=addend; s5.f3+=addend; s5.f4+=addend; s5.f5+=addend;
5842 return s5;
5845 typedef struct {
5846 char f1,f2,f3,f4,f5,f6;
5847 } sbyte6;
5849 LIBTEST_API sbyte6 STDCALL
5850 mono_return_sbyte6 (sbyte6 s6, int addend) {
5851 if (s6.f1 != 1) {
5852 fprintf(stderr, "mono_return_sbyte6 s6.f1: got %d but expected %d\n", s6.f1, 1);
5854 if (s6.f2 != 2) {
5855 fprintf(stderr, "mono_return_sbyte6 s6.f2: got %d but expected %d\n", s6.f2, 2);
5857 if (s6.f3 != 3) {
5858 fprintf(stderr, "mono_return_sbyte6 s6.f3: got %d but expected %d\n", s6.f3, 3);
5860 if (s6.f4 != 4) {
5861 fprintf(stderr, "mono_return_sbyte6 s6.f4: got %d but expected %d\n", s6.f4, 4);
5863 if (s6.f5 != 5) {
5864 fprintf(stderr, "mono_return_sbyte6 s6.f5: got %d but expected %d\n", s6.f5, 5);
5866 if (s6.f6 != 6) {
5867 fprintf(stderr, "mono_return_sbyte6 s6.f6: got %d but expected %d\n", s6.f6, 6);
5869 s6.f1+=addend; s6.f2+=addend; s6.f3+=addend; s6.f4+=addend; s6.f5+=addend; s6.f6+=addend;
5870 return s6;
5873 typedef struct {
5874 char f1,f2,f3,f4,f5,f6,f7;
5875 } sbyte7;
5877 LIBTEST_API sbyte7 STDCALL
5878 mono_return_sbyte7 (sbyte7 s7, int addend) {
5879 if (s7.f1 != 1) {
5880 fprintf(stderr, "mono_return_sbyte7 s7.f1: got %d but expected %d\n", s7.f1, 1);
5882 if (s7.f2 != 2) {
5883 fprintf(stderr, "mono_return_sbyte7 s7.f2: got %d but expected %d\n", s7.f2, 2);
5885 if (s7.f3 != 3) {
5886 fprintf(stderr, "mono_return_sbyte7 s7.f3: got %d but expected %d\n", s7.f3, 3);
5888 if (s7.f4 != 4) {
5889 fprintf(stderr, "mono_return_sbyte7 s7.f4: got %d but expected %d\n", s7.f4, 4);
5891 if (s7.f5 != 5) {
5892 fprintf(stderr, "mono_return_sbyte7 s7.f5: got %d but expected %d\n", s7.f5, 5);
5894 if (s7.f6 != 6) {
5895 fprintf(stderr, "mono_return_sbyte7 s7.f6: got %d but expected %d\n", s7.f6, 6);
5897 if (s7.f7 != 7) {
5898 fprintf(stderr, "mono_return_sbyte7 s7.f7: got %d but expected %d\n", s7.f7, 7);
5900 s7.f1+=addend; s7.f2+=addend; s7.f3+=addend; s7.f4+=addend; s7.f5+=addend; s7.f6+=addend; s7.f7+=addend;
5901 return s7;
5904 typedef struct {
5905 char f1,f2,f3,f4,f5,f6,f7,f8;
5906 } sbyte8;
5908 LIBTEST_API sbyte8 STDCALL
5909 mono_return_sbyte8 (sbyte8 s8, int addend) {
5910 if (s8.f1 != 1) {
5911 fprintf(stderr, "mono_return_sbyte8 s8.f1: got %d but expected %d\n", s8.f1, 1);
5913 if (s8.f2 != 2) {
5914 fprintf(stderr, "mono_return_sbyte8 s8.f2: got %d but expected %d\n", s8.f2, 2);
5916 if (s8.f3 != 3) {
5917 fprintf(stderr, "mono_return_sbyte8 s8.f3: got %d but expected %d\n", s8.f3, 3);
5919 if (s8.f4 != 4) {
5920 fprintf(stderr, "mono_return_sbyte8 s8.f4: got %d but expected %d\n", s8.f4, 4);
5922 if (s8.f5 != 5) {
5923 fprintf(stderr, "mono_return_sbyte8 s8.f5: got %d but expected %d\n", s8.f5, 5);
5925 if (s8.f6 != 6) {
5926 fprintf(stderr, "mono_return_sbyte8 s8.f6: got %d but expected %d\n", s8.f6, 6);
5928 if (s8.f7 != 7) {
5929 fprintf(stderr, "mono_return_sbyte8 s8.f7: got %d but expected %d\n", s8.f7, 7);
5931 if (s8.f8 != 8) {
5932 fprintf(stderr, "mono_return_sbyte8 s8.f8: got %d but expected %d\n", s8.f8, 8);
5934 s8.f1+=addend; s8.f2+=addend; s8.f3+=addend; s8.f4+=addend; s8.f5+=addend; s8.f6+=addend; s8.f7+=addend; s8.f8+=addend;
5935 return s8;
5938 typedef struct {
5939 char f1,f2,f3,f4,f5,f6,f7,f8,f9;
5940 } sbyte9;
5942 LIBTEST_API sbyte9 STDCALL
5943 mono_return_sbyte9 (sbyte9 s9, int addend) {
5944 if (s9.f1 != 1) {
5945 fprintf(stderr, "mono_return_sbyte9 s9.f1: got %d but expected %d\n", s9.f1, 1);
5947 if (s9.f2 != 2) {
5948 fprintf(stderr, "mono_return_sbyte9 s9.f2: got %d but expected %d\n", s9.f2, 2);
5950 if (s9.f3 != 3) {
5951 fprintf(stderr, "mono_return_sbyte9 s9.f3: got %d but expected %d\n", s9.f3, 3);
5953 if (s9.f4 != 4) {
5954 fprintf(stderr, "mono_return_sbyte9 s9.f4: got %d but expected %d\n", s9.f4, 4);
5956 if (s9.f5 != 5) {
5957 fprintf(stderr, "mono_return_sbyte9 s9.f5: got %d but expected %d\n", s9.f5, 5);
5959 if (s9.f6 != 6) {
5960 fprintf(stderr, "mono_return_sbyte9 s9.f6: got %d but expected %d\n", s9.f6, 6);
5962 if (s9.f7 != 7) {
5963 fprintf(stderr, "mono_return_sbyte9 s9.f7: got %d but expected %d\n", s9.f7, 7);
5965 if (s9.f8 != 8) {
5966 fprintf(stderr, "mono_return_sbyte9 s9.f8: got %d but expected %d\n", s9.f8, 8);
5968 if (s9.f9 != 9) {
5969 fprintf(stderr, "mono_return_sbyte9 s9.f9: got %d but expected %d\n", s9.f9, 9);
5971 s9.f1+=addend; s9.f2+=addend; s9.f3+=addend; s9.f4+=addend; s9.f5+=addend; s9.f6+=addend; s9.f7+=addend; s9.f8+=addend; s9.f9+=addend;
5972 return s9;
5975 typedef struct {
5976 char f1,f2,f3,f4,f5,f6,f7,f8,f9,f10;
5977 } sbyte10;
5979 LIBTEST_API sbyte10 STDCALL
5980 mono_return_sbyte10 (sbyte10 s10, int addend) {
5981 if (s10.f1 != 1) {
5982 fprintf(stderr, "mono_return_sbyte10 s10.f1: got %d but expected %d\n", s10.f1, 1);
5984 if (s10.f2 != 2) {
5985 fprintf(stderr, "mono_return_sbyte10 s10.f2: got %d but expected %d\n", s10.f2, 2);
5987 if (s10.f3 != 3) {
5988 fprintf(stderr, "mono_return_sbyte10 s10.f3: got %d but expected %d\n", s10.f3, 3);
5990 if (s10.f4 != 4) {
5991 fprintf(stderr, "mono_return_sbyte10 s10.f4: got %d but expected %d\n", s10.f4, 4);
5993 if (s10.f5 != 5) {
5994 fprintf(stderr, "mono_return_sbyte10 s10.f5: got %d but expected %d\n", s10.f5, 5);
5996 if (s10.f6 != 6) {
5997 fprintf(stderr, "mono_return_sbyte10 s10.f6: got %d but expected %d\n", s10.f6, 6);
5999 if (s10.f7 != 7) {
6000 fprintf(stderr, "mono_return_sbyte10 s10.f7: got %d but expected %d\n", s10.f7, 7);
6002 if (s10.f8 != 8) {
6003 fprintf(stderr, "mono_return_sbyte10 s10.f8: got %d but expected %d\n", s10.f8, 8);
6005 if (s10.f9 != 9) {
6006 fprintf(stderr, "mono_return_sbyte10 s10.f9: got %d but expected %d\n", s10.f9, 9);
6008 if (s10.f10 != 10) {
6009 fprintf(stderr, "mono_return_sbyte10 s10.f10: got %d but expected %d\n", s10.f10, 10);
6011 s10.f1+=addend; s10.f2+=addend; s10.f3+=addend; s10.f4+=addend; s10.f5+=addend; s10.f6+=addend; s10.f7+=addend; s10.f8+=addend; s10.f9+=addend; s10.f10+=addend;
6012 return s10;
6015 typedef struct {
6016 char f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11;
6017 } sbyte11;
6019 LIBTEST_API sbyte11 STDCALL
6020 mono_return_sbyte11 (sbyte11 s11, int addend) {
6021 if (s11.f1 != 1) {
6022 fprintf(stderr, "mono_return_sbyte11 s11.f1: got %d but expected %d\n", s11.f1, 1);
6024 if (s11.f2 != 2) {
6025 fprintf(stderr, "mono_return_sbyte11 s11.f2: got %d but expected %d\n", s11.f2, 2);
6027 if (s11.f3 != 3) {
6028 fprintf(stderr, "mono_return_sbyte11 s11.f3: got %d but expected %d\n", s11.f3, 3);
6030 if (s11.f4 != 4) {
6031 fprintf(stderr, "mono_return_sbyte11 s11.f4: got %d but expected %d\n", s11.f4, 4);
6033 if (s11.f5 != 5) {
6034 fprintf(stderr, "mono_return_sbyte11 s11.f5: got %d but expected %d\n", s11.f5, 5);
6036 if (s11.f6 != 6) {
6037 fprintf(stderr, "mono_return_sbyte11 s11.f6: got %d but expected %d\n", s11.f6, 6);
6039 if (s11.f7 != 7) {
6040 fprintf(stderr, "mono_return_sbyte11 s11.f7: got %d but expected %d\n", s11.f7, 7);
6042 if (s11.f8 != 8) {
6043 fprintf(stderr, "mono_return_sbyte11 s11.f8: got %d but expected %d\n", s11.f8, 8);
6045 if (s11.f9 != 9) {
6046 fprintf(stderr, "mono_return_sbyte11 s11.f9: got %d but expected %d\n", s11.f9, 9);
6048 if (s11.f10 != 10) {
6049 fprintf(stderr, "mono_return_sbyte11 s11.f10: got %d but expected %d\n", s11.f10, 10);
6051 if (s11.f11 != 11) {
6052 fprintf(stderr, "mono_return_sbyte11 s11.f11: got %d but expected %d\n", s11.f11, 11);
6054 s11.f1+=addend; s11.f2+=addend; s11.f3+=addend; s11.f4+=addend; s11.f5+=addend; s11.f6+=addend; s11.f7+=addend; s11.f8+=addend; s11.f9+=addend; s11.f10+=addend; s11.f11+=addend;
6055 return s11;
6058 typedef struct {
6059 char f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12;
6060 } sbyte12;
6062 LIBTEST_API sbyte12 STDCALL
6063 mono_return_sbyte12 (sbyte12 s12, int addend) {
6064 if (s12.f1 != 1) {
6065 fprintf(stderr, "mono_return_sbyte12 s12.f1: got %d but expected %d\n", s12.f1, 1);
6067 if (s12.f2 != 2) {
6068 fprintf(stderr, "mono_return_sbyte12 s12.f2: got %d but expected %d\n", s12.f2, 2);
6070 if (s12.f3 != 3) {
6071 fprintf(stderr, "mono_return_sbyte12 s12.f3: got %d but expected %d\n", s12.f3, 3);
6073 if (s12.f4 != 4) {
6074 fprintf(stderr, "mono_return_sbyte12 s12.f4: got %d but expected %d\n", s12.f4, 4);
6076 if (s12.f5 != 5) {
6077 fprintf(stderr, "mono_return_sbyte12 s12.f5: got %d but expected %d\n", s12.f5, 5);
6079 if (s12.f6 != 6) {
6080 fprintf(stderr, "mono_return_sbyte12 s12.f6: got %d but expected %d\n", s12.f6, 6);
6082 if (s12.f7 != 7) {
6083 fprintf(stderr, "mono_return_sbyte12 s12.f7: got %d but expected %d\n", s12.f7, 7);
6085 if (s12.f8 != 8) {
6086 fprintf(stderr, "mono_return_sbyte12 s12.f8: got %d but expected %d\n", s12.f8, 8);
6088 if (s12.f9 != 9) {
6089 fprintf(stderr, "mono_return_sbyte12 s12.f9: got %d but expected %d\n", s12.f9, 9);
6091 if (s12.f10 != 10) {
6092 fprintf(stderr, "mono_return_sbyte12 s12.f10: got %d but expected %d\n", s12.f10, 10);
6094 if (s12.f11 != 11) {
6095 fprintf(stderr, "mono_return_sbyte12 s12.f11: got %d but expected %d\n", s12.f11, 11);
6097 if (s12.f12 != 12) {
6098 fprintf(stderr, "mono_return_sbyte12 s12.f12: got %d but expected %d\n", s12.f12, 12);
6100 s12.f1+=addend; s12.f2+=addend; s12.f3+=addend; s12.f4+=addend; s12.f5+=addend; s12.f6+=addend; s12.f7+=addend; s12.f8+=addend; s12.f9+=addend; s12.f10+=addend; s12.f11+=addend; s12.f12+=addend;
6101 return s12;
6104 typedef struct {
6105 char f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13;
6106 } sbyte13;
6108 LIBTEST_API sbyte13 STDCALL
6109 mono_return_sbyte13 (sbyte13 s13, int addend) {
6110 if (s13.f1 != 1) {
6111 fprintf(stderr, "mono_return_sbyte13 s13.f1: got %d but expected %d\n", s13.f1, 1);
6113 if (s13.f2 != 2) {
6114 fprintf(stderr, "mono_return_sbyte13 s13.f2: got %d but expected %d\n", s13.f2, 2);
6116 if (s13.f3 != 3) {
6117 fprintf(stderr, "mono_return_sbyte13 s13.f3: got %d but expected %d\n", s13.f3, 3);
6119 if (s13.f4 != 4) {
6120 fprintf(stderr, "mono_return_sbyte13 s13.f4: got %d but expected %d\n", s13.f4, 4);
6122 if (s13.f5 != 5) {
6123 fprintf(stderr, "mono_return_sbyte13 s13.f5: got %d but expected %d\n", s13.f5, 5);
6125 if (s13.f6 != 6) {
6126 fprintf(stderr, "mono_return_sbyte13 s13.f6: got %d but expected %d\n", s13.f6, 6);
6128 if (s13.f7 != 7) {
6129 fprintf(stderr, "mono_return_sbyte13 s13.f7: got %d but expected %d\n", s13.f7, 7);
6131 if (s13.f8 != 8) {
6132 fprintf(stderr, "mono_return_sbyte13 s13.f8: got %d but expected %d\n", s13.f8, 8);
6134 if (s13.f9 != 9) {
6135 fprintf(stderr, "mono_return_sbyte13 s13.f9: got %d but expected %d\n", s13.f9, 9);
6137 if (s13.f10 != 10) {
6138 fprintf(stderr, "mono_return_sbyte13 s13.f10: got %d but expected %d\n", s13.f10, 10);
6140 if (s13.f11 != 11) {
6141 fprintf(stderr, "mono_return_sbyte13 s13.f11: got %d but expected %d\n", s13.f11, 11);
6143 if (s13.f12 != 12) {
6144 fprintf(stderr, "mono_return_sbyte13 s13.f12: got %d but expected %d\n", s13.f12, 12);
6146 if (s13.f13 != 13) {
6147 fprintf(stderr, "mono_return_sbyte13 s13.f13: got %d but expected %d\n", s13.f13, 13);
6149 s13.f1+=addend; s13.f2+=addend; s13.f3+=addend; s13.f4+=addend; s13.f5+=addend; s13.f6+=addend; s13.f7+=addend; s13.f8+=addend; s13.f9+=addend; s13.f10+=addend; s13.f11+=addend; s13.f12+=addend; s13.f13+=addend;
6150 return s13;
6153 typedef struct {
6154 char f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14;
6155 } sbyte14;
6157 LIBTEST_API sbyte14 STDCALL
6158 mono_return_sbyte14 (sbyte14 s14, int addend) {
6159 if (s14.f1 != 1) {
6160 fprintf(stderr, "mono_return_sbyte14 s14.f1: got %d but expected %d\n", s14.f1, 1);
6162 if (s14.f2 != 2) {
6163 fprintf(stderr, "mono_return_sbyte14 s14.f2: got %d but expected %d\n", s14.f2, 2);
6165 if (s14.f3 != 3) {
6166 fprintf(stderr, "mono_return_sbyte14 s14.f3: got %d but expected %d\n", s14.f3, 3);
6168 if (s14.f4 != 4) {
6169 fprintf(stderr, "mono_return_sbyte14 s14.f4: got %d but expected %d\n", s14.f4, 4);
6171 if (s14.f5 != 5) {
6172 fprintf(stderr, "mono_return_sbyte14 s14.f5: got %d but expected %d\n", s14.f5, 5);
6174 if (s14.f6 != 6) {
6175 fprintf(stderr, "mono_return_sbyte14 s14.f6: got %d but expected %d\n", s14.f6, 6);
6177 if (s14.f7 != 7) {
6178 fprintf(stderr, "mono_return_sbyte14 s14.f7: got %d but expected %d\n", s14.f7, 7);
6180 if (s14.f8 != 8) {
6181 fprintf(stderr, "mono_return_sbyte14 s14.f8: got %d but expected %d\n", s14.f8, 8);
6183 if (s14.f9 != 9) {
6184 fprintf(stderr, "mono_return_sbyte14 s14.f9: got %d but expected %d\n", s14.f9, 9);
6186 if (s14.f10 != 10) {
6187 fprintf(stderr, "mono_return_sbyte14 s14.f10: got %d but expected %d\n", s14.f10, 10);
6189 if (s14.f11 != 11) {
6190 fprintf(stderr, "mono_return_sbyte14 s14.f11: got %d but expected %d\n", s14.f11, 11);
6192 if (s14.f12 != 12) {
6193 fprintf(stderr, "mono_return_sbyte14 s14.f12: got %d but expected %d\n", s14.f12, 12);
6195 if (s14.f13 != 13) {
6196 fprintf(stderr, "mono_return_sbyte14 s14.f13: got %d but expected %d\n", s14.f13, 13);
6198 if (s14.f14 != 14) {
6199 fprintf(stderr, "mono_return_sbyte14 s14.f14: got %d but expected %d\n", s14.f14, 14);
6201 s14.f1+=addend; s14.f2+=addend; s14.f3+=addend; s14.f4+=addend; s14.f5+=addend; s14.f6+=addend; s14.f7+=addend; s14.f8+=addend; s14.f9+=addend; s14.f10+=addend; s14.f11+=addend; s14.f12+=addend; s14.f13+=addend; s14.f14+=addend;
6202 return s14;
6205 typedef struct {
6206 char f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15;
6207 } sbyte15;
6209 LIBTEST_API sbyte15 STDCALL
6210 mono_return_sbyte15 (sbyte15 s15, int addend) {
6211 if (s15.f1 != 1) {
6212 fprintf(stderr, "mono_return_sbyte15 s15.f1: got %d but expected %d\n", s15.f1, 1);
6214 if (s15.f2 != 2) {
6215 fprintf(stderr, "mono_return_sbyte15 s15.f2: got %d but expected %d\n", s15.f2, 2);
6217 if (s15.f3 != 3) {
6218 fprintf(stderr, "mono_return_sbyte15 s15.f3: got %d but expected %d\n", s15.f3, 3);
6220 if (s15.f4 != 4) {
6221 fprintf(stderr, "mono_return_sbyte15 s15.f4: got %d but expected %d\n", s15.f4, 4);
6223 if (s15.f5 != 5) {
6224 fprintf(stderr, "mono_return_sbyte15 s15.f5: got %d but expected %d\n", s15.f5, 5);
6226 if (s15.f6 != 6) {
6227 fprintf(stderr, "mono_return_sbyte15 s15.f6: got %d but expected %d\n", s15.f6, 6);
6229 if (s15.f7 != 7) {
6230 fprintf(stderr, "mono_return_sbyte15 s15.f7: got %d but expected %d\n", s15.f7, 7);
6232 if (s15.f8 != 8) {
6233 fprintf(stderr, "mono_return_sbyte15 s15.f8: got %d but expected %d\n", s15.f8, 8);
6235 if (s15.f9 != 9) {
6236 fprintf(stderr, "mono_return_sbyte15 s15.f9: got %d but expected %d\n", s15.f9, 9);
6238 if (s15.f10 != 10) {
6239 fprintf(stderr, "mono_return_sbyte15 s15.f10: got %d but expected %d\n", s15.f10, 10);
6241 if (s15.f11 != 11) {
6242 fprintf(stderr, "mono_return_sbyte15 s15.f11: got %d but expected %d\n", s15.f11, 11);
6244 if (s15.f12 != 12) {
6245 fprintf(stderr, "mono_return_sbyte15 s15.f12: got %d but expected %d\n", s15.f12, 12);
6247 if (s15.f13 != 13) {
6248 fprintf(stderr, "mono_return_sbyte15 s15.f13: got %d but expected %d\n", s15.f13, 13);
6250 if (s15.f14 != 14) {
6251 fprintf(stderr, "mono_return_sbyte15 s15.f14: got %d but expected %d\n", s15.f14, 14);
6253 if (s15.f15 != 15) {
6254 fprintf(stderr, "mono_return_sbyte15 s15.f15: got %d but expected %d\n", s15.f15, 15);
6256 s15.f1+=addend; s15.f2+=addend; s15.f3+=addend; s15.f4+=addend; s15.f5+=addend; s15.f6+=addend; s15.f7+=addend; s15.f8+=addend; s15.f9+=addend; s15.f10+=addend; s15.f11+=addend; s15.f12+=addend; s15.f13+=addend; s15.f14+=addend; s15.f15+=addend;
6257 return s15;
6260 typedef struct {
6261 char f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16;
6262 } sbyte16;
6264 LIBTEST_API sbyte16 STDCALL
6265 mono_return_sbyte16 (sbyte16 s16, int addend) {
6266 if (s16.f1 != 1) {
6267 fprintf(stderr, "mono_return_sbyte16 s16.f1: got %d but expected %d\n", s16.f1, 1);
6269 if (s16.f2 != 2) {
6270 fprintf(stderr, "mono_return_sbyte16 s16.f2: got %d but expected %d\n", s16.f2, 2);
6272 if (s16.f3 != 3) {
6273 fprintf(stderr, "mono_return_sbyte16 s16.f3: got %d but expected %d\n", s16.f3, 3);
6275 if (s16.f4 != 4) {
6276 fprintf(stderr, "mono_return_sbyte16 s16.f4: got %d but expected %d\n", s16.f4, 4);
6278 if (s16.f5 != 5) {
6279 fprintf(stderr, "mono_return_sbyte16 s16.f5: got %d but expected %d\n", s16.f5, 5);
6281 if (s16.f6 != 6) {
6282 fprintf(stderr, "mono_return_sbyte16 s16.f6: got %d but expected %d\n", s16.f6, 6);
6284 if (s16.f7 != 7) {
6285 fprintf(stderr, "mono_return_sbyte16 s16.f7: got %d but expected %d\n", s16.f7, 7);
6287 if (s16.f8 != 8) {
6288 fprintf(stderr, "mono_return_sbyte16 s16.f8: got %d but expected %d\n", s16.f8, 8);
6290 if (s16.f9 != 9) {
6291 fprintf(stderr, "mono_return_sbyte16 s16.f9: got %d but expected %d\n", s16.f9, 9);
6293 if (s16.f10 != 10) {
6294 fprintf(stderr, "mono_return_sbyte16 s16.f10: got %d but expected %d\n", s16.f10, 10);
6296 if (s16.f11 != 11) {
6297 fprintf(stderr, "mono_return_sbyte16 s16.f11: got %d but expected %d\n", s16.f11, 11);
6299 if (s16.f12 != 12) {
6300 fprintf(stderr, "mono_return_sbyte16 s16.f12: got %d but expected %d\n", s16.f12, 12);
6302 if (s16.f13 != 13) {
6303 fprintf(stderr, "mono_return_sbyte16 s16.f13: got %d but expected %d\n", s16.f13, 13);
6305 if (s16.f14 != 14) {
6306 fprintf(stderr, "mono_return_sbyte16 s16.f14: got %d but expected %d\n", s16.f14, 14);
6308 if (s16.f15 != 15) {
6309 fprintf(stderr, "mono_return_sbyte16 s16.f15: got %d but expected %d\n", s16.f15, 15);
6311 if (s16.f16 != 16) {
6312 fprintf(stderr, "mono_return_sbyte16 s16.f16: got %d but expected %d\n", s16.f16, 16);
6314 s16.f1+=addend; s16.f2+=addend; s16.f3+=addend; s16.f4+=addend; s16.f5+=addend; s16.f6+=addend; s16.f7+=addend; s16.f8+=addend; s16.f9+=addend; s16.f10+=addend; s16.f11+=addend; s16.f12+=addend; s16.f13+=addend; s16.f14+=addend; s16.f15+=addend; s16.f16+=addend;
6315 return s16;
6318 typedef struct {
6319 char f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16,f17;
6320 } sbyte17;
6322 LIBTEST_API sbyte17 STDCALL
6323 mono_return_sbyte17 (sbyte17 s17, int addend) {
6324 if (s17.f1 != 1) {
6325 fprintf(stderr, "mono_return_sbyte17 s17.f1: got %d but expected %d\n", s17.f1, 1);
6327 if (s17.f2 != 2) {
6328 fprintf(stderr, "mono_return_sbyte17 s17.f2: got %d but expected %d\n", s17.f2, 2);
6330 if (s17.f3 != 3) {
6331 fprintf(stderr, "mono_return_sbyte17 s17.f3: got %d but expected %d\n", s17.f3, 3);
6333 if (s17.f4 != 4) {
6334 fprintf(stderr, "mono_return_sbyte17 s17.f4: got %d but expected %d\n", s17.f4, 4);
6336 if (s17.f5 != 5) {
6337 fprintf(stderr, "mono_return_sbyte17 s17.f5: got %d but expected %d\n", s17.f5, 5);
6339 if (s17.f6 != 6) {
6340 fprintf(stderr, "mono_return_sbyte17 s17.f6: got %d but expected %d\n", s17.f6, 6);
6342 if (s17.f7 != 7) {
6343 fprintf(stderr, "mono_return_sbyte17 s17.f7: got %d but expected %d\n", s17.f7, 7);
6345 if (s17.f8 != 8) {
6346 fprintf(stderr, "mono_return_sbyte17 s17.f8: got %d but expected %d\n", s17.f8, 8);
6348 if (s17.f9 != 9) {
6349 fprintf(stderr, "mono_return_sbyte17 s17.f9: got %d but expected %d\n", s17.f9, 9);
6351 if (s17.f10 != 10) {
6352 fprintf(stderr, "mono_return_sbyte17 s17.f10: got %d but expected %d\n", s17.f10, 10);
6354 if (s17.f11 != 11) {
6355 fprintf(stderr, "mono_return_sbyte17 s17.f11: got %d but expected %d\n", s17.f11, 11);
6357 if (s17.f12 != 12) {
6358 fprintf(stderr, "mono_return_sbyte17 s17.f12: got %d but expected %d\n", s17.f12, 12);
6360 if (s17.f13 != 13) {
6361 fprintf(stderr, "mono_return_sbyte17 s17.f13: got %d but expected %d\n", s17.f13, 13);
6363 if (s17.f14 != 14) {
6364 fprintf(stderr, "mono_return_sbyte17 s17.f14: got %d but expected %d\n", s17.f14, 14);
6366 if (s17.f15 != 15) {
6367 fprintf(stderr, "mono_return_sbyte17 s17.f15: got %d but expected %d\n", s17.f15, 15);
6369 if (s17.f16 != 16) {
6370 fprintf(stderr, "mono_return_sbyte17 s17.f16: got %d but expected %d\n", s17.f16, 16);
6372 if (s17.f17 != 17) {
6373 fprintf(stderr, "mono_return_sbyte17 s17.f17: got %d but expected %d\n", s17.f17, 17);
6375 s17.f1+=addend; s17.f2+=addend; s17.f3+=addend; s17.f4+=addend; s17.f5+=addend; s17.f6+=addend; s17.f7+=addend; s17.f8+=addend; s17.f9+=addend; s17.f10+=addend; s17.f11+=addend; s17.f12+=addend; s17.f13+=addend; s17.f14+=addend; s17.f15+=addend; s17.f16+=addend; s17.f17+=addend;
6376 return s17;
6379 typedef struct {
6380 struct {
6381 char f1;
6382 } nested1;
6383 char f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15;
6384 struct {
6385 char f16;
6386 } nested2;
6387 } sbyte16_nested;
6389 LIBTEST_API sbyte16_nested STDCALL
6390 mono_return_sbyte16_nested (sbyte16_nested sn16, int addend) {
6391 if (sn16.nested1.f1 != 1) {
6392 fprintf(stderr, "mono_return_sbyte16_nested sn16.nested1.f1: got %d but expected %d\n", sn16.nested1.f1, 1);
6394 if (sn16.f2 != 2) {
6395 fprintf(stderr, "mono_return_sbyte16_nested sn16.f2: got %d but expected %d\n", sn16.f2, 2);
6397 if (sn16.f3 != 3) {
6398 fprintf(stderr, "mono_return_sbyte16_nested sn16.f3: got %d but expected %d\n", sn16.f3, 3);
6400 if (sn16.f4 != 4) {
6401 fprintf(stderr, "mono_return_sbyte16_nested sn16.f4: got %d but expected %d\n", sn16.f4, 4);
6403 if (sn16.f5 != 5) {
6404 fprintf(stderr, "mono_return_sbyte16_nested sn16.f5: got %d but expected %d\n", sn16.f5, 5);
6406 if (sn16.f6 != 6) {
6407 fprintf(stderr, "mono_return_sbyte16_nested sn16.f6: got %d but expected %d\n", sn16.f6, 6);
6409 if (sn16.f7 != 7) {
6410 fprintf(stderr, "mono_return_sbyte16_nested sn16.f7: got %d but expected %d\n", sn16.f7, 7);
6412 if (sn16.f8 != 8) {
6413 fprintf(stderr, "mono_return_sbyte16_nested sn16.f8: got %d but expected %d\n", sn16.f8, 8);
6415 if (sn16.f9 != 9) {
6416 fprintf(stderr, "mono_return_sbyte16_nested sn16.f9: got %d but expected %d\n", sn16.f9, 9);
6418 if (sn16.f10 != 10) {
6419 fprintf(stderr, "mono_return_sbyte16_nested sn16.f10: got %d but expected %d\n", sn16.f10, 10);
6421 if (sn16.f11 != 11) {
6422 fprintf(stderr, "mono_return_sbyte16_nested sn16.f11: got %d but expected %d\n", sn16.f11, 11);
6424 if (sn16.f12 != 12) {
6425 fprintf(stderr, "mono_return_sbyte16_nested sn16.f12: got %d but expected %d\n", sn16.f12, 12);
6427 if (sn16.f13 != 13) {
6428 fprintf(stderr, "mono_return_sbyte16_nested sn16.f13: got %d but expected %d\n", sn16.f13, 13);
6430 if (sn16.f14 != 14) {
6431 fprintf(stderr, "mono_return_sbyte16_nested sn16.f14: got %d but expected %d\n", sn16.f14, 14);
6433 if (sn16.f15 != 15) {
6434 fprintf(stderr, "mono_return_sbyte16_nested sn16.f15: got %d but expected %d\n", sn16.f15, 15);
6436 if (sn16.nested2.f16 != 16) {
6437 fprintf(stderr, "mono_return_sbyte16_nested sn16.nested2.f16: got %d but expected %d\n", sn16.nested2.f16, 16);
6439 sn16.nested1.f1+=addend; sn16.f2+=addend; sn16.f3+=addend; sn16.f4+=addend; sn16.f5+=addend; sn16.f6+=addend; sn16.f7+=addend; sn16.f8+=addend; sn16.f9+=addend; sn16.f10+=addend; sn16.f11+=addend; sn16.f12+=addend; sn16.f13+=addend; sn16.f14+=addend; sn16.f15+=addend; sn16.nested2.f16+=addend;
6440 return sn16;
6444 typedef struct {
6445 short f1;
6446 } short1;
6448 LIBTEST_API short1 STDCALL
6449 mono_return_short1 (short1 s1, int addend) {
6450 if (s1.f1 != 1) {
6451 fprintf(stderr, "mono_return_short1 s1.f1: got %d but expected %d\n", s1.f1, 1);
6453 s1.f1+=addend;
6454 return s1;
6457 typedef struct {
6458 short f1,f2;
6459 } short2;
6461 LIBTEST_API short2 STDCALL
6462 mono_return_short2 (short2 s2, int addend) {
6463 if (s2.f1 != 1) {
6464 fprintf(stderr, "mono_return_short2 s2.f1: got %d but expected %d\n", s2.f1, 1);
6466 if (s2.f2 != 2) {
6467 fprintf(stderr, "mono_return_short2 s2.f2: got %d but expected %d\n", s2.f2, 2);
6469 s2.f1+=addend; s2.f2+=addend;
6470 return s2;
6473 typedef struct {
6474 short f1,f2,f3;
6475 } short3;
6477 LIBTEST_API short3 STDCALL
6478 mono_return_short3 (short3 s3, int addend) {
6479 if (s3.f1 != 1) {
6480 fprintf(stderr, "mono_return_short3 s3.f1: got %d but expected %d\n", s3.f1, 1);
6482 if (s3.f2 != 2) {
6483 fprintf(stderr, "mono_return_short3 s3.f2: got %d but expected %d\n", s3.f2, 2);
6485 if (s3.f3 != 3) {
6486 fprintf(stderr, "mono_return_short3 s3.f3: got %d but expected %d\n", s3.f3, 3);
6488 s3.f1+=addend; s3.f2+=addend; s3.f3+=addend;
6489 return s3;
6492 typedef struct {
6493 short f1,f2,f3,f4;
6494 } short4;
6496 LIBTEST_API short4 STDCALL
6497 mono_return_short4 (short4 s4, int addend) {
6498 if (s4.f1 != 1) {
6499 fprintf(stderr, "mono_return_short4 s4.f1: got %d but expected %d\n", s4.f1, 1);
6501 if (s4.f2 != 2) {
6502 fprintf(stderr, "mono_return_short4 s4.f2: got %d but expected %d\n", s4.f2, 2);
6504 if (s4.f3 != 3) {
6505 fprintf(stderr, "mono_return_short4 s4.f3: got %d but expected %d\n", s4.f3, 3);
6507 if (s4.f4 != 4) {
6508 fprintf(stderr, "mono_return_short4 s4.f4: got %d but expected %d\n", s4.f4, 4);
6510 s4.f1+=addend; s4.f2+=addend; s4.f3+=addend; s4.f4+=addend;
6511 return s4;
6514 typedef struct {
6515 short f1,f2,f3,f4,f5;
6516 } short5;
6518 LIBTEST_API short5 STDCALL
6519 mono_return_short5 (short5 s5, int addend) {
6520 if (s5.f1 != 1) {
6521 fprintf(stderr, "mono_return_short5 s5.f1: got %d but expected %d\n", s5.f1, 1);
6523 if (s5.f2 != 2) {
6524 fprintf(stderr, "mono_return_short5 s5.f2: got %d but expected %d\n", s5.f2, 2);
6526 if (s5.f3 != 3) {
6527 fprintf(stderr, "mono_return_short5 s5.f3: got %d but expected %d\n", s5.f3, 3);
6529 if (s5.f4 != 4) {
6530 fprintf(stderr, "mono_return_short5 s5.f4: got %d but expected %d\n", s5.f4, 4);
6532 if (s5.f5 != 5) {
6533 fprintf(stderr, "mono_return_short5 s5.f5: got %d but expected %d\n", s5.f5, 5);
6535 s5.f1+=addend; s5.f2+=addend; s5.f3+=addend; s5.f4+=addend; s5.f5+=addend;
6536 return s5;
6539 typedef struct {
6540 short f1,f2,f3,f4,f5,f6;
6541 } short6;
6543 LIBTEST_API short6 STDCALL
6544 mono_return_short6 (short6 s6, int addend) {
6545 if (s6.f1 != 1) {
6546 fprintf(stderr, "mono_return_short6 s6.f1: got %d but expected %d\n", s6.f1, 1);
6548 if (s6.f2 != 2) {
6549 fprintf(stderr, "mono_return_short6 s6.f2: got %d but expected %d\n", s6.f2, 2);
6551 if (s6.f3 != 3) {
6552 fprintf(stderr, "mono_return_short6 s6.f3: got %d but expected %d\n", s6.f3, 3);
6554 if (s6.f4 != 4) {
6555 fprintf(stderr, "mono_return_short6 s6.f4: got %d but expected %d\n", s6.f4, 4);
6557 if (s6.f5 != 5) {
6558 fprintf(stderr, "mono_return_short6 s6.f5: got %d but expected %d\n", s6.f5, 5);
6560 if (s6.f6 != 6) {
6561 fprintf(stderr, "mono_return_short6 s6.f6: got %d but expected %d\n", s6.f6, 6);
6563 s6.f1+=addend; s6.f2+=addend; s6.f3+=addend; s6.f4+=addend; s6.f5+=addend; s6.f6+=addend;
6564 return s6;
6567 typedef struct {
6568 short f1,f2,f3,f4,f5,f6,f7;
6569 } short7;
6571 LIBTEST_API short7 STDCALL
6572 mono_return_short7 (short7 s7, int addend) {
6573 if (s7.f1 != 1) {
6574 fprintf(stderr, "mono_return_short7 s7.f1: got %d but expected %d\n", s7.f1, 1);
6576 if (s7.f2 != 2) {
6577 fprintf(stderr, "mono_return_short7 s7.f2: got %d but expected %d\n", s7.f2, 2);
6579 if (s7.f3 != 3) {
6580 fprintf(stderr, "mono_return_short7 s7.f3: got %d but expected %d\n", s7.f3, 3);
6582 if (s7.f4 != 4) {
6583 fprintf(stderr, "mono_return_short7 s7.f4: got %d but expected %d\n", s7.f4, 4);
6585 if (s7.f5 != 5) {
6586 fprintf(stderr, "mono_return_short7 s7.f5: got %d but expected %d\n", s7.f5, 5);
6588 if (s7.f6 != 6) {
6589 fprintf(stderr, "mono_return_short7 s7.f6: got %d but expected %d\n", s7.f6, 6);
6591 if (s7.f7 != 7) {
6592 fprintf(stderr, "mono_return_short7 s7.f7: got %d but expected %d\n", s7.f7, 7);
6594 s7.f1+=addend; s7.f2+=addend; s7.f3+=addend; s7.f4+=addend; s7.f5+=addend; s7.f6+=addend; s7.f7+=addend;
6595 return s7;
6598 typedef struct {
6599 short f1,f2,f3,f4,f5,f6,f7,f8;
6600 } short8;
6602 LIBTEST_API short8 STDCALL
6603 mono_return_short8 (short8 s8, int addend) {
6604 if (s8.f1 != 1) {
6605 fprintf(stderr, "mono_return_short8 s8.f1: got %d but expected %d\n", s8.f1, 1);
6607 if (s8.f2 != 2) {
6608 fprintf(stderr, "mono_return_short8 s8.f2: got %d but expected %d\n", s8.f2, 2);
6610 if (s8.f3 != 3) {
6611 fprintf(stderr, "mono_return_short8 s8.f3: got %d but expected %d\n", s8.f3, 3);
6613 if (s8.f4 != 4) {
6614 fprintf(stderr, "mono_return_short8 s8.f4: got %d but expected %d\n", s8.f4, 4);
6616 if (s8.f5 != 5) {
6617 fprintf(stderr, "mono_return_short8 s8.f5: got %d but expected %d\n", s8.f5, 5);
6619 if (s8.f6 != 6) {
6620 fprintf(stderr, "mono_return_short8 s8.f6: got %d but expected %d\n", s8.f6, 6);
6622 if (s8.f7 != 7) {
6623 fprintf(stderr, "mono_return_short8 s8.f7: got %d but expected %d\n", s8.f7, 7);
6625 if (s8.f8 != 8) {
6626 fprintf(stderr, "mono_return_short8 s8.f8: got %d but expected %d\n", s8.f8, 8);
6628 s8.f1+=addend; s8.f2+=addend; s8.f3+=addend; s8.f4+=addend; s8.f5+=addend; s8.f6+=addend; s8.f7+=addend; s8.f8+=addend;
6629 return s8;
6632 typedef struct {
6633 short f1,f2,f3,f4,f5,f6,f7,f8,f9;
6634 } short9;
6636 LIBTEST_API short9 STDCALL
6637 mono_return_short9 (short9 s9, int addend) {
6638 if (s9.f1 != 1) {
6639 fprintf(stderr, "mono_return_short9 s9.f1: got %d but expected %d\n", s9.f1, 1);
6641 if (s9.f2 != 2) {
6642 fprintf(stderr, "mono_return_short9 s9.f2: got %d but expected %d\n", s9.f2, 2);
6644 if (s9.f3 != 3) {
6645 fprintf(stderr, "mono_return_short9 s9.f3: got %d but expected %d\n", s9.f3, 3);
6647 if (s9.f4 != 4) {
6648 fprintf(stderr, "mono_return_short9 s9.f4: got %d but expected %d\n", s9.f4, 4);
6650 if (s9.f5 != 5) {
6651 fprintf(stderr, "mono_return_short9 s9.f5: got %d but expected %d\n", s9.f5, 5);
6653 if (s9.f6 != 6) {
6654 fprintf(stderr, "mono_return_short9 s9.f6: got %d but expected %d\n", s9.f6, 6);
6656 if (s9.f7 != 7) {
6657 fprintf(stderr, "mono_return_short9 s9.f7: got %d but expected %d\n", s9.f7, 7);
6659 if (s9.f8 != 8) {
6660 fprintf(stderr, "mono_return_short9 s9.f8: got %d but expected %d\n", s9.f8, 8);
6662 if (s9.f9 != 9) {
6663 fprintf(stderr, "mono_return_short9 s9.f9: got %d but expected %d\n", s9.f9, 9);
6665 s9.f1+=addend; s9.f2+=addend; s9.f3+=addend; s9.f4+=addend; s9.f5+=addend; s9.f6+=addend; s9.f7+=addend; s9.f8+=addend; s9.f9+=addend;
6666 return s9;
6669 typedef struct {
6670 struct {
6671 short f1;
6672 } nested1;
6673 short f2,f3,f4,f5,f6,f7;
6674 struct {
6675 short f8;
6676 } nested2;
6677 } short8_nested;
6679 LIBTEST_API short8_nested STDCALL
6680 mono_return_short8_nested (short8_nested sn8, int addend) {
6681 if (sn8.nested1.f1 != 1) {
6682 fprintf(stderr, "mono_return_short8_nested sn8.nested1.f1: got %d but expected %d\n", sn8.nested1.f1, 1);
6684 if (sn8.f2 != 2) {
6685 fprintf(stderr, "mono_return_short8_nested sn8.f2: got %d but expected %d\n", sn8.f2, 2);
6687 if (sn8.f3 != 3) {
6688 fprintf(stderr, "mono_return_short8_nested sn8.f3: got %d but expected %d\n", sn8.f3, 3);
6690 if (sn8.f4 != 4) {
6691 fprintf(stderr, "mono_return_short8_nested sn8.f4: got %d but expected %d\n", sn8.f4, 4);
6693 if (sn8.f5 != 5) {
6694 fprintf(stderr, "mono_return_short8_nested sn8.f5: got %d but expected %d\n", sn8.f5, 5);
6696 if (sn8.f6 != 6) {
6697 fprintf(stderr, "mono_return_short8_nested sn8.f6: got %d but expected %d\n", sn8.f6, 6);
6699 if (sn8.f7 != 7) {
6700 fprintf(stderr, "mono_return_short8_nested sn8.f7: got %d but expected %d\n", sn8.f7, 7);
6702 if (sn8.nested2.f8 != 8) {
6703 fprintf(stderr, "mono_return_short8_nested sn8.nested2.f8: got %d but expected %d\n", sn8.nested2.f8, 8);
6705 sn8.nested1.f1+=addend; sn8.f2+=addend; sn8.f3+=addend; sn8.f4+=addend; sn8.f5+=addend; sn8.f6+=addend; sn8.f7+=addend; sn8.nested2.f8+=addend;
6706 return sn8;
6710 typedef struct {
6711 int f1;
6712 } int1;
6714 LIBTEST_API int1 STDCALL
6715 mono_return_int1 (int1 s1, int addend) {
6716 if (s1.f1 != 1) {
6717 fprintf(stderr, "mono_return_int1 s1.f1: got %d but expected %d\n", s1.f1, 1);
6719 s1.f1+=addend;
6720 return s1;
6723 typedef struct {
6724 int f1,f2;
6725 } int2;
6727 LIBTEST_API int2 STDCALL
6728 mono_return_int2 (int2 s2, int addend) {
6729 if (s2.f1 != 1) {
6730 fprintf(stderr, "mono_return_int2 s2.f1: got %d but expected %d\n", s2.f1, 1);
6732 if (s2.f2 != 2) {
6733 fprintf(stderr, "mono_return_int2 s2.f2: got %d but expected %d\n", s2.f2, 2);
6735 s2.f1+=addend; s2.f2+=addend;
6736 return s2;
6739 typedef struct {
6740 int f1,f2,f3;
6741 } int3;
6743 LIBTEST_API int3 STDCALL
6744 mono_return_int3 (int3 s3, int addend) {
6745 if (s3.f1 != 1) {
6746 fprintf(stderr, "mono_return_int3 s3.f1: got %d but expected %d\n", s3.f1, 1);
6748 if (s3.f2 != 2) {
6749 fprintf(stderr, "mono_return_int3 s3.f2: got %d but expected %d\n", s3.f2, 2);
6751 if (s3.f3 != 3) {
6752 fprintf(stderr, "mono_return_int3 s3.f3: got %d but expected %d\n", s3.f3, 3);
6754 s3.f1+=addend; s3.f2+=addend; s3.f3+=addend;
6755 return s3;
6758 typedef struct {
6759 int f1,f2,f3,f4;
6760 } int4;
6762 LIBTEST_API int4 STDCALL
6763 mono_return_int4 (int4 s4, int addend) {
6764 if (s4.f1 != 1) {
6765 fprintf(stderr, "mono_return_int4 s4.f1: got %d but expected %d\n", s4.f1, 1);
6767 if (s4.f2 != 2) {
6768 fprintf(stderr, "mono_return_int4 s4.f2: got %d but expected %d\n", s4.f2, 2);
6770 if (s4.f3 != 3) {
6771 fprintf(stderr, "mono_return_int4 s4.f3: got %d but expected %d\n", s4.f3, 3);
6773 if (s4.f4 != 4) {
6774 fprintf(stderr, "mono_return_int4 s4.f4: got %d but expected %d\n", s4.f4, 4);
6776 s4.f1+=addend; s4.f2+=addend; s4.f3+=addend; s4.f4+=addend;
6777 return s4;
6780 typedef struct {
6781 int f1,f2,f3,f4,f5;
6782 } int5;
6784 LIBTEST_API int5 STDCALL
6785 mono_return_int5 (int5 s5, int addend) {
6786 if (s5.f1 != 1) {
6787 fprintf(stderr, "mono_return_int5 s5.f1: got %d but expected %d\n", s5.f1, 1);
6789 if (s5.f2 != 2) {
6790 fprintf(stderr, "mono_return_int5 s5.f2: got %d but expected %d\n", s5.f2, 2);
6792 if (s5.f3 != 3) {
6793 fprintf(stderr, "mono_return_int5 s5.f3: got %d but expected %d\n", s5.f3, 3);
6795 if (s5.f4 != 4) {
6796 fprintf(stderr, "mono_return_int5 s5.f4: got %d but expected %d\n", s5.f4, 4);
6798 if (s5.f5 != 5) {
6799 fprintf(stderr, "mono_return_int5 s5.f5: got %d but expected %d\n", s5.f5, 5);
6801 s5.f1+=addend; s5.f2+=addend; s5.f3+=addend; s5.f4+=addend; s5.f5+=addend;
6802 return s5;
6805 typedef struct {
6806 struct {
6807 int f1;
6808 } nested1;
6809 int f2,f3;
6810 struct {
6811 int f4;
6812 } nested2;
6813 } int4_nested;
6815 LIBTEST_API int4_nested STDCALL
6816 mono_return_int4_nested (int4_nested sn4, int addend) {
6817 if (sn4.nested1.f1 != 1) {
6818 fprintf(stderr, "mono_return_int4_nested sn4.nested1.f1: got %d but expected %d\n", sn4.nested1.f1, 1);
6820 if (sn4.f2 != 2) {
6821 fprintf(stderr, "mono_return_int4_nested sn4.f2: got %d but expected %d\n", sn4.f2, 2);
6823 if (sn4.f3 != 3) {
6824 fprintf(stderr, "mono_return_int4_nested sn4.f3: got %d but expected %d\n", sn4.f3, 3);
6826 if (sn4.nested2.f4 != 4) {
6827 fprintf(stderr, "mono_return_int4_nested sn4.nested2.f4: got %d but expected %d\n", sn4.nested2.f4, 4);
6829 sn4.nested1.f1+=addend; sn4.f2+=addend; sn4.f3+=addend; sn4.nested2.f4+=addend;
6830 return sn4;
6833 typedef struct {
6834 float f1;
6835 } float1;
6837 LIBTEST_API float1 STDCALL
6838 mono_return_float1 (float1 s1, int addend) {
6839 if (s1.f1 != 1) {
6840 fprintf(stderr, "mono_return_float1 s1.f1: got %f but expected %d\n", s1.f1, 1);
6842 s1.f1+=addend;
6843 return s1;
6846 typedef struct {
6847 float f1,f2;
6848 } float2;
6850 LIBTEST_API float2 STDCALL
6851 mono_return_float2 (float2 s2, int addend) {
6852 if (s2.f1 != 1) {
6853 fprintf(stderr, "mono_return_float2 s2.f1: got %f but expected %d\n", s2.f1, 1);
6855 if (s2.f2 != 2) {
6856 fprintf(stderr, "mono_return_float2 s2.f2: got %f but expected %d\n", s2.f2, 2);
6858 s2.f1+=addend; s2.f2+=addend;
6859 return s2;
6862 typedef struct {
6863 float f1,f2,f3;
6864 } float3;
6866 LIBTEST_API float3 STDCALL
6867 mono_return_float3 (float3 s3, int addend) {
6868 if (s3.f1 != 1) {
6869 fprintf(stderr, "mono_return_float3 s3.f1: got %f but expected %d\n", s3.f1, 1);
6871 if (s3.f2 != 2) {
6872 fprintf(stderr, "mono_return_float3 s3.f2: got %f but expected %d\n", s3.f2, 2);
6874 if (s3.f3 != 3) {
6875 fprintf(stderr, "mono_return_float3 s3.f3: got %f but expected %d\n", s3.f3, 3);
6877 s3.f1+=addend; s3.f2+=addend; s3.f3+=addend;
6878 return s3;
6881 typedef struct {
6882 float f1,f2,f3,f4;
6883 } float4;
6885 LIBTEST_API float4 STDCALL
6886 mono_return_float4 (float4 s4, int addend) {
6887 if (s4.f1 != 1) {
6888 fprintf(stderr, "mono_return_float4 s4.f1: got %f but expected %d\n", s4.f1, 1);
6890 if (s4.f2 != 2) {
6891 fprintf(stderr, "mono_return_float4 s4.f2: got %f but expected %d\n", s4.f2, 2);
6893 if (s4.f3 != 3) {
6894 fprintf(stderr, "mono_return_float4 s4.f3: got %f but expected %d\n", s4.f3, 3);
6896 if (s4.f4 != 4) {
6897 fprintf(stderr, "mono_return_float4 s4.f4: got %f but expected %d\n", s4.f4, 4);
6899 s4.f1+=addend; s4.f2+=addend; s4.f3+=addend; s4.f4+=addend;
6900 return s4;
6903 typedef struct {
6904 float f1,f2,f3,f4,f5;
6905 } float5;
6907 LIBTEST_API float5 STDCALL
6908 mono_return_float5 (float5 s5, int addend) {
6909 if (s5.f1 != 1) {
6910 fprintf(stderr, "mono_return_float5 s5.f1: got %f but expected %d\n", s5.f1, 1);
6912 if (s5.f2 != 2) {
6913 fprintf(stderr, "mono_return_float5 s5.f2: got %f but expected %d\n", s5.f2, 2);
6915 if (s5.f3 != 3) {
6916 fprintf(stderr, "mono_return_float5 s5.f3: got %f but expected %d\n", s5.f3, 3);
6918 if (s5.f4 != 4) {
6919 fprintf(stderr, "mono_return_float5 s5.f4: got %f but expected %d\n", s5.f4, 4);
6921 if (s5.f5 != 5) {
6922 fprintf(stderr, "mono_return_float5 s5.f5: got %f but expected %d\n", s5.f5, 5);
6924 s5.f1+=addend; s5.f2+=addend; s5.f3+=addend; s5.f4+=addend; s5.f5+=addend;
6925 return s5;
6928 typedef struct {
6929 float f1,f2,f3,f4,f5,f6;
6930 } float6;
6932 LIBTEST_API float6 STDCALL
6933 mono_return_float6 (float6 s6, int addend) {
6934 if (s6.f1 != 1) {
6935 fprintf(stderr, "mono_return_float6 s6.f1: got %f but expected %d\n", s6.f1, 1);
6937 if (s6.f2 != 2) {
6938 fprintf(stderr, "mono_return_float6 s6.f2: got %f but expected %d\n", s6.f2, 2);
6940 if (s6.f3 != 3) {
6941 fprintf(stderr, "mono_return_float6 s6.f3: got %f but expected %d\n", s6.f3, 3);
6943 if (s6.f4 != 4) {
6944 fprintf(stderr, "mono_return_float6 s6.f4: got %f but expected %d\n", s6.f4, 4);
6946 if (s6.f5 != 5) {
6947 fprintf(stderr, "mono_return_float6 s6.f5: got %f but expected %d\n", s6.f5, 5);
6949 if (s6.f6 != 6) {
6950 fprintf(stderr, "mono_return_float6 s6.f6: got %f but expected %d\n", s6.f6, 6);
6952 s6.f1+=addend; s6.f2+=addend; s6.f3+=addend; s6.f4+=addend; s6.f5+=addend; s6.f6+=addend;
6953 return s6;
6956 typedef struct {
6957 float f1,f2,f3,f4,f5,f6,f7;
6958 } float7;
6960 LIBTEST_API float7 STDCALL
6961 mono_return_float7 (float7 s7, int addend) {
6962 if (s7.f1 != 1) {
6963 fprintf(stderr, "mono_return_float7 s7.f1: got %f but expected %d\n", s7.f1, 1);
6965 if (s7.f2 != 2) {
6966 fprintf(stderr, "mono_return_float7 s7.f2: got %f but expected %d\n", s7.f2, 2);
6968 if (s7.f3 != 3) {
6969 fprintf(stderr, "mono_return_float7 s7.f3: got %f but expected %d\n", s7.f3, 3);
6971 if (s7.f4 != 4) {
6972 fprintf(stderr, "mono_return_float7 s7.f4: got %f but expected %d\n", s7.f4, 4);
6974 if (s7.f5 != 5) {
6975 fprintf(stderr, "mono_return_float7 s7.f5: got %f but expected %d\n", s7.f5, 5);
6977 if (s7.f6 != 6) {
6978 fprintf(stderr, "mono_return_float7 s7.f6: got %f but expected %d\n", s7.f6, 6);
6980 if (s7.f7 != 7) {
6981 fprintf(stderr, "mono_return_float7 s7.f7: got %f but expected %d\n", s7.f7, 7);
6983 s7.f1+=addend; s7.f2+=addend; s7.f3+=addend; s7.f4+=addend; s7.f5+=addend; s7.f6+=addend; s7.f7+=addend;
6984 return s7;
6987 typedef struct {
6988 float f1,f2,f3,f4,f5,f6,f7,f8;
6989 } float8;
6991 LIBTEST_API float8 STDCALL
6992 mono_return_float8 (float8 s8, int addend) {
6993 if (s8.f1 != 1) {
6994 fprintf(stderr, "mono_return_float8 s8.f1: got %f but expected %d\n", s8.f1, 1);
6996 if (s8.f2 != 2) {
6997 fprintf(stderr, "mono_return_float8 s8.f2: got %f but expected %d\n", s8.f2, 2);
6999 if (s8.f3 != 3) {
7000 fprintf(stderr, "mono_return_float8 s8.f3: got %f but expected %d\n", s8.f3, 3);
7002 if (s8.f4 != 4) {
7003 fprintf(stderr, "mono_return_float8 s8.f4: got %f but expected %d\n", s8.f4, 4);
7005 if (s8.f5 != 5) {
7006 fprintf(stderr, "mono_return_float8 s8.f5: got %f but expected %d\n", s8.f5, 5);
7008 if (s8.f6 != 6) {
7009 fprintf(stderr, "mono_return_float8 s8.f6: got %f but expected %d\n", s8.f6, 6);
7011 if (s8.f7 != 7) {
7012 fprintf(stderr, "mono_return_float8 s8.f7: got %f but expected %d\n", s8.f7, 7);
7014 if (s8.f8 != 8) {
7015 fprintf(stderr, "mono_return_float8 s8.f8: got %f but expected %d\n", s8.f8, 8);
7017 s8.f1+=addend; s8.f2+=addend; s8.f3+=addend; s8.f4+=addend; s8.f5+=addend; s8.f6+=addend; s8.f7+=addend; s8.f8+=addend;
7018 return s8;
7021 typedef struct {
7022 float f1,f2,f3,f4,f5,f6,f7,f8,f9;
7023 } float9;
7025 LIBTEST_API float9 STDCALL
7026 mono_return_float9 (float9 s9, int addend) {
7027 if (s9.f1 != 1) {
7028 fprintf(stderr, "mono_return_float9 s9.f1: got %f but expected %d\n", s9.f1, 1);
7030 if (s9.f2 != 2) {
7031 fprintf(stderr, "mono_return_float9 s9.f2: got %f but expected %d\n", s9.f2, 2);
7033 if (s9.f3 != 3) {
7034 fprintf(stderr, "mono_return_float9 s9.f3: got %f but expected %d\n", s9.f3, 3);
7036 if (s9.f4 != 4) {
7037 fprintf(stderr, "mono_return_float9 s9.f4: got %f but expected %d\n", s9.f4, 4);
7039 if (s9.f5 != 5) {
7040 fprintf(stderr, "mono_return_float9 s9.f5: got %f but expected %d\n", s9.f5, 5);
7042 if (s9.f6 != 6) {
7043 fprintf(stderr, "mono_return_float9 s9.f6: got %f but expected %d\n", s9.f6, 6);
7045 if (s9.f7 != 7) {
7046 fprintf(stderr, "mono_return_float9 s9.f7: got %f but expected %d\n", s9.f7, 7);
7048 if (s9.f8 != 8) {
7049 fprintf(stderr, "mono_return_float9 s9.f8: got %f but expected %d\n", s9.f8, 8);
7051 if (s9.f9 != 9) {
7052 fprintf(stderr, "mono_return_float9 s9.f9: got %f but expected %d\n", s9.f9, 9);
7054 s9.f1+=addend; s9.f2+=addend; s9.f3+=addend; s9.f4+=addend; s9.f5+=addend; s9.f6+=addend; s9.f7+=addend; s9.f8+=addend; s9.f9+=addend;
7055 return s9;
7058 typedef struct {
7059 struct {
7060 float f1;
7061 } nested1;
7062 float f2,f3;
7063 struct {
7064 float f4;
7065 } nested2;
7066 } float4_nested;
7068 LIBTEST_API float4_nested STDCALL
7069 mono_return_float4_nested (float4_nested sn4, int addend) {
7070 if (sn4.nested1.f1 != 1) {
7071 fprintf(stderr, "mono_return_float4_nested sn4.nested1.f1: got %f but expected %d\n", sn4.nested1.f1, 1);
7073 if (sn4.f2 != 2) {
7074 fprintf(stderr, "mono_return_float4_nested sn4.f2: got %f but expected %d\n", sn4.f2, 2);
7076 if (sn4.f3 != 3) {
7077 fprintf(stderr, "mono_return_float4_nested sn4.f3: got %f but expected %d\n", sn4.f3, 3);
7079 if (sn4.nested2.f4 != 4) {
7080 fprintf(stderr, "mono_return_float4_nested sn4.nested2.f4: got %f but expected %d\n", sn4.nested2.f4, 4);
7082 sn4.nested1.f1+=addend; sn4.f2+=addend; sn4.f3+=addend; sn4.nested2.f4+=addend;
7083 return sn4;
7086 typedef struct {
7087 double f1;
7088 } double1;
7090 LIBTEST_API double1 STDCALL
7091 mono_return_double1 (double1 s1, int addend) {
7092 if (s1.f1 != 1) {
7093 fprintf(stderr, "mono_return_double1 s1.f1: got %f but expected %d\n", s1.f1, 1);
7095 s1.f1+=addend;
7096 return s1;
7099 typedef struct {
7100 double f1,f2;
7101 } double2;
7103 LIBTEST_API double2 STDCALL
7104 mono_return_double2 (double2 s2, int addend) {
7105 if (s2.f1 != 1) {
7106 fprintf(stderr, "mono_return_double2 s2.f1: got %f but expected %d\n", s2.f1, 1);
7108 if (s2.f2 != 2) {
7109 fprintf(stderr, "mono_return_double2 s2.f2: got %f but expected %d\n", s2.f2, 2);
7111 s2.f1+=addend; s2.f2+=addend;
7112 return s2;
7115 typedef struct {
7116 double f1,f2,f3;
7117 } double3;
7119 LIBTEST_API double3 STDCALL
7120 mono_return_double3 (double3 s3, int addend) {
7121 if (s3.f1 != 1) {
7122 fprintf(stderr, "mono_return_double3 s3.f1: got %f but expected %d\n", s3.f1, 1);
7124 if (s3.f2 != 2) {
7125 fprintf(stderr, "mono_return_double3 s3.f2: got %f but expected %d\n", s3.f2, 2);
7127 if (s3.f3 != 3) {
7128 fprintf(stderr, "mono_return_double3 s3.f3: got %f but expected %d\n", s3.f3, 3);
7130 s3.f1+=addend; s3.f2+=addend; s3.f3+=addend;
7131 return s3;
7134 typedef struct {
7135 double f1,f2,f3,f4;
7136 } double4;
7138 LIBTEST_API double4 STDCALL
7139 mono_return_double4 (double4 s4, int addend) {
7140 if (s4.f1 != 1) {
7141 fprintf(stderr, "mono_return_double4 s4.f1: got %f but expected %d\n", s4.f1, 1);
7143 if (s4.f2 != 2) {
7144 fprintf(stderr, "mono_return_double4 s4.f2: got %f but expected %d\n", s4.f2, 2);
7146 if (s4.f3 != 3) {
7147 fprintf(stderr, "mono_return_double4 s4.f3: got %f but expected %d\n", s4.f3, 3);
7149 if (s4.f4 != 4) {
7150 fprintf(stderr, "mono_return_double4 s4.f4: got %f but expected %d\n", s4.f4, 4);
7152 s4.f1+=addend; s4.f2+=addend; s4.f3+=addend; s4.f4+=addend;
7153 return s4;
7156 typedef struct {
7157 double f1,f2,f3,f4,f5;
7158 } double5;
7160 LIBTEST_API double5 STDCALL
7161 mono_return_double5 (double5 s5, int addend) {
7162 if (s5.f1 != 1) {
7163 fprintf(stderr, "mono_return_double5 s5.f1: got %f but expected %d\n", s5.f1, 1);
7165 if (s5.f2 != 2) {
7166 fprintf(stderr, "mono_return_double5 s5.f2: got %f but expected %d\n", s5.f2, 2);
7168 if (s5.f3 != 3) {
7169 fprintf(stderr, "mono_return_double5 s5.f3: got %f but expected %d\n", s5.f3, 3);
7171 if (s5.f4 != 4) {
7172 fprintf(stderr, "mono_return_double5 s5.f4: got %f but expected %d\n", s5.f4, 4);
7174 if (s5.f5 != 5) {
7175 fprintf(stderr, "mono_return_double5 s5.f5: got %f but expected %d\n", s5.f5, 5);
7177 s5.f1+=addend; s5.f2+=addend; s5.f3+=addend; s5.f4+=addend; s5.f5+=addend;
7178 return s5;
7181 typedef struct {
7182 double f1,f2,f3,f4,f5,f6;
7183 } double6;
7185 LIBTEST_API double6 STDCALL
7186 mono_return_double6 (double6 s6, int addend) {
7187 if (s6.f1 != 1) {
7188 fprintf(stderr, "mono_return_double6 s6.f1: got %f but expected %d\n", s6.f1, 1);
7190 if (s6.f2 != 2) {
7191 fprintf(stderr, "mono_return_double6 s6.f2: got %f but expected %d\n", s6.f2, 2);
7193 if (s6.f3 != 3) {
7194 fprintf(stderr, "mono_return_double6 s6.f3: got %f but expected %d\n", s6.f3, 3);
7196 if (s6.f4 != 4) {
7197 fprintf(stderr, "mono_return_double6 s6.f4: got %f but expected %d\n", s6.f4, 4);
7199 if (s6.f5 != 5) {
7200 fprintf(stderr, "mono_return_double6 s6.f5: got %f but expected %d\n", s6.f5, 5);
7202 if (s6.f6 != 6) {
7203 fprintf(stderr, "mono_return_double6 s6.f6: got %f but expected %d\n", s6.f6, 6);
7205 s6.f1+=addend; s6.f2+=addend; s6.f3+=addend; s6.f4+=addend; s6.f5+=addend; s6.f6+=addend;
7206 return s6;
7209 typedef struct {
7210 double f1,f2,f3,f4,f5,f6,f7;
7211 } double7;
7213 LIBTEST_API double7 STDCALL
7214 mono_return_double7 (double7 s7, int addend) {
7215 if (s7.f1 != 1) {
7216 fprintf(stderr, "mono_return_double7 s7.f1: got %f but expected %d\n", s7.f1, 1);
7218 if (s7.f2 != 2) {
7219 fprintf(stderr, "mono_return_double7 s7.f2: got %f but expected %d\n", s7.f2, 2);
7221 if (s7.f3 != 3) {
7222 fprintf(stderr, "mono_return_double7 s7.f3: got %f but expected %d\n", s7.f3, 3);
7224 if (s7.f4 != 4) {
7225 fprintf(stderr, "mono_return_double7 s7.f4: got %f but expected %d\n", s7.f4, 4);
7227 if (s7.f5 != 5) {
7228 fprintf(stderr, "mono_return_double7 s7.f5: got %f but expected %d\n", s7.f5, 5);
7230 if (s7.f6 != 6) {
7231 fprintf(stderr, "mono_return_double7 s7.f6: got %f but expected %d\n", s7.f6, 6);
7233 if (s7.f7 != 7) {
7234 fprintf(stderr, "mono_return_double7 s7.f7: got %f but expected %d\n", s7.f7, 7);
7236 s7.f1+=addend; s7.f2+=addend; s7.f3+=addend; s7.f4+=addend; s7.f5+=addend; s7.f6+=addend; s7.f7+=addend;
7237 return s7;
7240 typedef struct {
7241 double f1,f2,f3,f4,f5,f6,f7,f8;
7242 } double8;
7244 LIBTEST_API double8 STDCALL
7245 mono_return_double8 (double8 s8, int addend) {
7246 if (s8.f1 != 1) {
7247 fprintf(stderr, "mono_return_double8 s8.f1: got %f but expected %d\n", s8.f1, 1);
7249 if (s8.f2 != 2) {
7250 fprintf(stderr, "mono_return_double8 s8.f2: got %f but expected %d\n", s8.f2, 2);
7252 if (s8.f3 != 3) {
7253 fprintf(stderr, "mono_return_double8 s8.f3: got %f but expected %d\n", s8.f3, 3);
7255 if (s8.f4 != 4) {
7256 fprintf(stderr, "mono_return_double8 s8.f4: got %f but expected %d\n", s8.f4, 4);
7258 if (s8.f5 != 5) {
7259 fprintf(stderr, "mono_return_double8 s8.f5: got %f but expected %d\n", s8.f5, 5);
7261 if (s8.f6 != 6) {
7262 fprintf(stderr, "mono_return_double8 s8.f6: got %f but expected %d\n", s8.f6, 6);
7264 if (s8.f7 != 7) {
7265 fprintf(stderr, "mono_return_double8 s8.f7: got %f but expected %d\n", s8.f7, 7);
7267 if (s8.f8 != 8) {
7268 fprintf(stderr, "mono_return_double8 s8.f8: got %f but expected %d\n", s8.f8, 8);
7270 s8.f1+=addend; s8.f2+=addend; s8.f3+=addend; s8.f4+=addend; s8.f5+=addend; s8.f6+=addend; s8.f7+=addend; s8.f8+=addend;
7271 return s8;
7274 typedef struct {
7275 double f1,f2,f3,f4,f5,f6,f7,f8,f9;
7276 } double9;
7278 LIBTEST_API double9 STDCALL
7279 mono_return_double9 (double9 s9, int addend) {
7280 if (s9.f1 != 1) {
7281 fprintf(stderr, "mono_return_double9 s9.f1: got %f but expected %d\n", s9.f1, 1);
7283 if (s9.f2 != 2) {
7284 fprintf(stderr, "mono_return_double9 s9.f2: got %f but expected %d\n", s9.f2, 2);
7286 if (s9.f3 != 3) {
7287 fprintf(stderr, "mono_return_double9 s9.f3: got %f but expected %d\n", s9.f3, 3);
7289 if (s9.f4 != 4) {
7290 fprintf(stderr, "mono_return_double9 s9.f4: got %f but expected %d\n", s9.f4, 4);
7292 if (s9.f5 != 5) {
7293 fprintf(stderr, "mono_return_double9 s9.f5: got %f but expected %d\n", s9.f5, 5);
7295 if (s9.f6 != 6) {
7296 fprintf(stderr, "mono_return_double9 s9.f6: got %f but expected %d\n", s9.f6, 6);
7298 if (s9.f7 != 7) {
7299 fprintf(stderr, "mono_return_double9 s9.f7: got %f but expected %d\n", s9.f7, 7);
7301 if (s9.f8 != 8) {
7302 fprintf(stderr, "mono_return_double9 s9.f8: got %f but expected %d\n", s9.f8, 8);
7304 if (s9.f9 != 9) {
7305 fprintf(stderr, "mono_return_double9 s9.f9: got %f but expected %d\n", s9.f9, 9);
7307 s9.f1+=addend; s9.f2+=addend; s9.f3+=addend; s9.f4+=addend; s9.f5+=addend; s9.f6+=addend; s9.f7+=addend; s9.f8+=addend; s9.f9+=addend;
7308 return s9;
7311 typedef struct {
7312 struct {
7313 double f1;
7314 } nested1;
7315 struct {
7316 double f2;
7317 } nested2;
7318 } double2_nested;
7320 LIBTEST_API double2_nested STDCALL
7321 mono_return_double2_nested (double2_nested sn2, int addend) {
7322 if (sn2.nested1.f1 != 1) {
7323 fprintf(stderr, "mono_return_double2_nested sn2.nested1.f1: got %f but expected %d\n", sn2.nested1.f1, 1);
7325 if (sn2.nested2.f2 != 2) {
7326 fprintf(stderr, "mono_return_double2_nested sn2.nested2.f2: got %f but expected %d\n", sn2.nested2.f2, 2);
7328 sn2.nested1.f1+=addend; sn2.nested2.f2+=addend;
7329 return sn2;
7334 typedef struct {
7335 double f1[4];
7336 } double_array4;
7338 LIBTEST_API double_array4 STDCALL
7339 mono_return_double_array4 (double_array4 sa4, int addend) {
7340 if (sa4.f1[0] != 1) {
7341 fprintf(stderr, "mono_return_double_array4 sa4.f1[0]: got %f but expected %d\n", sa4.f1[0], 1);
7343 if (sa4.f1[1] != 2) {
7344 fprintf(stderr, "mono_return_double_array4 sa4.f1[1]: got %f but expected %d\n", sa4.f1[1], 2);
7346 if (sa4.f1[2] != 3) {
7347 fprintf(stderr, "mono_return_double_array4 sa4.f1[2]: got %f but expected %d\n", sa4.f1[2], 3);
7349 if (sa4.f1[3] != 4) {
7350 fprintf(stderr, "mono_return_double_array4 sa4.f1[3]: got %f but expected %d\n", sa4.f1[3], 4);
7352 sa4.f1[0]+=addend; sa4.f1[1]+=addend; sa4.f1[2]+=addend; sa4.f1[3]+=addend;
7353 return sa4;
7356 typedef struct {
7357 int array [3];
7358 } FixedArrayStruct;
7360 LIBTEST_API int STDCALL
7361 mono_test_marshal_fixed_array (FixedArrayStruct s)
7363 return s.array [0] + s.array [1] + s.array [2];
7366 typedef struct {
7367 char array [16];
7368 char c;
7369 } FixedBufferChar;
7371 LIBTEST_API int STDCALL
7372 mono_test_marshal_fixed_buffer_char (FixedBufferChar *s)
7374 if (!(s->array [0] == 'A' && s->array [1] == 'B' && s->array [2] == 'C' && s->c == 'D'))
7375 return 1;
7376 s->array [0] = 'E';
7377 s->array [1] = 'F';
7378 s->c = 'G';
7379 return 0;
7382 typedef struct {
7383 short array [16];
7384 short c;
7385 } FixedBufferUnicode;
7387 LIBTEST_API int STDCALL
7388 mono_test_marshal_fixed_buffer_unicode (FixedBufferUnicode *s)
7390 if (!(s->array [0] == 'A' && s->array [1] == 'B' && s->array [2] == 'C' && s->c == 'D'))
7391 return 1;
7392 s->array [0] = 'E';
7393 s->array [1] = 'F';
7394 s->c = 'G';
7395 return 0;
7398 const int NSTRINGS = 6;
7399 //test strings
7400 const char *utf8Strings[] = {
7401 "Managed",
7402 "Sîne klâwen durh die wolken sint geslagen" ,
7403 "काचं शक्नोम्यत्तुम् । नोपहिनस्ति माम्",
7404 "我能吞下玻璃而不伤身体",
7405 "ღმერთსი შემვედრე,შემვედრე, ნუთუ კვლა დამხსნას შემვედრე,სოფლისა შემვედრე, შემვედრე,შემვედრე,შემვედრე,შრომასა, ცეცხლს, წყალსა და მიწასა, ჰაერთა თანა მრომასა; მომცნეს ფრთენი და აღვფრინდე, მივჰხვდე მას ჩემსა ნდომასა, დღისით და ღამით ვჰხედვიდე მზისა ელვათა კრთომაასაშემვედრე,შემვედრე,",
7406 "Τη γλώσσα μου έδωσαν ελληνική",
7407 "\0"
7410 LIBTEST_API char *
7411 build_return_string(const char* pReturn)
7413 char *ret = 0;
7414 if (pReturn == 0 || *pReturn == 0)
7415 return ret;
7417 size_t strLength = strlen(pReturn);
7418 ret = (char *)(marshal_alloc (sizeof(char)* (strLength + 1)));
7419 memcpy(ret, pReturn, strLength);
7420 ret [strLength] = '\0';
7421 return ret;
7424 LIBTEST_API char *
7425 StringParameterInOut(/*[In,Out]*/ char *s, int index)
7427 // return a copy
7428 return build_return_string(s);
7431 LIBTEST_API void
7432 StringParameterRefOut(/*out*/ char **s, int index)
7434 char *pszTextutf8 = (char*)utf8Strings[index];
7435 size_t strLength = strlen(pszTextutf8);
7436 *s = (char *)(marshal_alloc (sizeof(char)* (strLength + 1)));
7437 memcpy(*s, pszTextutf8, strLength);
7438 (*s)[strLength] = '\0';
7441 LIBTEST_API void
7442 StringParameterRef(/*ref*/ char **s, int index)
7444 char *pszTextutf8 = (char*)utf8Strings[index];
7445 size_t strLength = strlen(pszTextutf8);
7446 // do byte by byte validation of in string
7447 size_t szLen = strlen(*s);
7448 for (size_t i = 0; i < szLen; i++)
7450 if ((*s)[i] != pszTextutf8[i])
7452 printf("[in] managed string do not match native string\n");
7453 abort ();
7457 if (*s)
7459 marshal_free (*s);
7461 // overwrite the orginal
7462 *s = (char *)(marshal_alloc (sizeof(char)* (strLength + 1)));
7463 memcpy(*s, pszTextutf8, strLength);
7464 (*s)[strLength] = '\0';
7467 LIBTEST_API void
7468 StringBuilderParameterInOut(/*[In,Out] StringBuilder*/ char *s, int index)
7470 // if string.empty
7471 if (s == 0 || *s == 0)
7472 return;
7474 char *pszTextutf8 = (char*)utf8Strings[index];
7476 // do byte by byte validation of in string
7477 size_t szLen = strlen(s);
7478 for (size_t i = 0; i < szLen; i++)
7480 if (s[i] != pszTextutf8[i])
7482 printf("[in] managed string do not match native string\n");
7483 abort ();
7487 // modify the string inplace
7488 size_t outLen = strlen(pszTextutf8);
7489 for (size_t i = 0; i < outLen; i++) {
7490 s[i] = pszTextutf8[i];
7492 s[outLen] = '\0';
7495 //out string builder
7496 LIBTEST_API void
7497 StringBuilderParameterOut(/*[Out] StringBuilder*/ char *s, int index)
7499 char *pszTextutf8 = (char*)utf8Strings[index];
7501 printf ("SBPO: Receiving %s\n", s);
7502 // modify the string inplace
7503 size_t outLen = strlen(pszTextutf8);
7504 for (size_t i = 0; i < outLen; i++) {
7505 s[i] = pszTextutf8[i];
7507 s[outLen] = '\0';
7510 LIBTEST_API char *
7511 StringParameterOut(/*[Out]*/ char *s, int index)
7513 // return a copy
7514 return build_return_string(s);
7517 // Utf8 field
7518 typedef struct FieldWithUtf8
7520 char *pFirst;
7521 int index;
7522 }FieldWithUtf8;
7524 //utf8 struct field
7525 LIBTEST_API void
7526 TestStructWithUtf8Field(struct FieldWithUtf8 fieldStruct)
7528 char *pszManagedutf8 = fieldStruct.pFirst;
7529 int stringIndex = fieldStruct.index;
7530 char *pszNative = 0;
7531 size_t outLen = 0;
7533 if (pszManagedutf8 == 0 || *pszManagedutf8 == 0)
7534 return;
7536 pszNative = (char*)utf8Strings[stringIndex];
7538 outLen = strlen(pszNative);
7539 // do byte by byte comparision
7540 for (size_t i = 0; i < outLen; i++)
7542 if (pszNative[i] != pszManagedutf8[i])
7544 printf("Native and managed string do not match.\n");
7545 abort ();
7550 typedef void (* Callback2)(char *text, int index);
7552 LIBTEST_API void
7553 Utf8DelegateAsParameter(Callback2 managedCallback)
7555 for (int i = 0; i < NSTRINGS; ++i)
7557 char *pszNative = 0;
7558 pszNative = (char*)utf8Strings[i];
7559 managedCallback(pszNative, i);
7564 LIBTEST_API char*
7565 StringBuilderParameterReturn(int index)
7567 char *pszTextutf8 = (char*)utf8Strings[index];
7568 size_t strLength = strlen(pszTextutf8);
7569 char * ret = (char *)(marshal_alloc (sizeof(char)* (strLength + 1)));
7570 memcpy(ret, pszTextutf8, strLength);
7571 ret[strLength] = '\0';
7573 return ret;
7576 LIBTEST_API int STDCALL
7577 mono_test_marshal_pointer_array (int *arr[])
7579 int i;
7581 for (i = 0; i < 10; ++i) {
7582 if (*arr [i] != -1)
7583 return 1;
7585 return 0;
7588 #ifndef WIN32
7590 typedef void (*NativeToManagedExceptionRethrowFunc) (void);
7592 void *mono_test_native_to_managed_exception_rethrow_thread (void *arg)
7594 NativeToManagedExceptionRethrowFunc func = (NativeToManagedExceptionRethrowFunc) arg;
7595 func ();
7596 return NULL;
7599 LIBTEST_API void STDCALL
7600 mono_test_native_to_managed_exception_rethrow (NativeToManagedExceptionRethrowFunc func)
7602 pthread_t t;
7603 pthread_create (&t, NULL, mono_test_native_to_managed_exception_rethrow_thread, func);
7604 pthread_join (t, NULL);
7606 #endif
7608 typedef void (*VoidVoidCallback) (void);
7609 typedef void (*MonoFtnPtrEHCallback) (guint32 gchandle);
7611 static jmp_buf test_jmp_buf;
7612 static guint32 test_gchandle;
7614 static void
7615 mono_test_longjmp_callback (guint32 gchandle)
7617 test_gchandle = gchandle;
7618 longjmp (test_jmp_buf, 1);
7621 LIBTEST_API void STDCALL
7622 mono_test_setjmp_and_call (VoidVoidCallback managedCallback, intptr_t *out_handle)
7624 void (*mono_install_ftnptr_eh_callback) (MonoFtnPtrEHCallback) =
7625 (void (*) (MonoFtnPtrEHCallback)) (lookup_mono_symbol ("mono_install_ftnptr_eh_callback"));
7626 if (setjmp (test_jmp_buf) == 0) {
7627 *out_handle = 0;
7628 mono_install_ftnptr_eh_callback (mono_test_longjmp_callback);
7629 managedCallback ();
7630 *out_handle = 0; /* Do not expect to return here */
7631 } else {
7632 mono_install_ftnptr_eh_callback (NULL);
7633 *out_handle = test_gchandle;