2010-06-17 Geoff Norton <gnorton@novell.com>
[mono.git] / mono / tests / libtest.c
blob7ff9a1acd033065d4286881a90641faa7a502c97
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>
11 #ifdef WIN32
12 #include <windows.h>
13 #include "initguid.h"
14 #endif
16 #ifdef WIN32
17 #define STDCALL __stdcall
18 #else
19 #define STDCALL
20 #endif
22 #ifdef __GNUC__
23 #pragma GCC diagnostic ignored "-Wmissing-prototypes"
24 #endif
26 #ifdef WIN32
27 extern __declspec(dllimport) void __stdcall CoTaskMemFree(void *ptr);
28 #endif
30 typedef int (STDCALL *SimpleDelegate) (int a);
32 #if defined(WIN32) && defined (_MSC_VER)
33 #define LIBTEST_API __declspec(dllexport)
34 #else
35 #define LIBTEST_API
36 #endif
38 static void marshal_free (void *ptr)
40 #ifdef WIN32
41 CoTaskMemFree (ptr);
42 #else
43 g_free (ptr);
44 #endif
47 static void* marshal_alloc (gsize size)
49 #ifdef WIN32
50 return CoTaskMemAlloc (size);
51 #else
52 return g_malloc (size);
53 #endif
56 static char* marshal_strdup (const char *str)
58 #ifdef WIN32
59 int len;
60 char *buf;
62 if (!str)
63 return NULL;
65 len = strlen (str);
66 buf = (char *) CoTaskMemAlloc (len + 1);
67 return strcpy (buf, str);
68 #else
69 return g_strdup (str);
70 #endif
73 static gunichar2* marshal_bstr_alloc(const gchar* str)
75 #ifdef WIN32
76 gunichar2* ret = NULL;
77 gunichar2* temp = NULL;
78 temp = g_utf8_to_utf16 (str, -1, NULL, NULL, NULL);
79 ret = SysAllocString (temp);
80 g_free (temp);
81 return ret;
82 #else
83 gchar* ret = NULL;
84 int slen = strlen (str);
85 gunichar2* temp;
86 /* allocate len + 1 utf16 characters plus 4 byte integer for length*/
87 ret = g_malloc ((slen + 1) * sizeof(gunichar2) + sizeof(guint32));
88 if (ret == NULL)
89 return NULL;
90 temp = g_utf8_to_utf16 (str, -1, NULL, NULL, NULL);
91 memcpy (ret + sizeof(guint32), temp, slen * sizeof(gunichar2));
92 * ((guint32 *) ret) = slen * sizeof(gunichar2);
93 ret [4 + slen * sizeof(gunichar2)] = 0;
94 ret [5 + slen * sizeof(gunichar2)] = 0;
96 return (gunichar2*)(ret + 4);
97 #endif
100 LIBTEST_API int STDCALL
101 mono_cominterop_is_supported (void)
103 #if defined(TARGET_X86) || defined(TARGET_AMD64)
104 return 1;
105 #endif
106 return 0;
109 LIBTEST_API unsigned short* STDCALL
110 test_lpwstr_marshal (unsigned short* chars, long length)
112 int i = 0;
113 unsigned short *res;
115 res = marshal_alloc (2 * (length + 1));
117 // printf("test_lpwstr_marshal()\n");
119 while ( i < length ) {
120 // printf("X|%u|\n", chars[i]);
121 res [i] = chars[i];
122 i++;
125 res [i] = 0;
127 return res;
131 LIBTEST_API void STDCALL
132 test_lpwstr_marshal_out (unsigned short** chars)
134 int i = 0;
135 const char abc[] = "ABC";
136 glong len = strlen(abc);
138 *chars = marshal_alloc (2 * (len + 1));
140 while ( i < len ) {
141 (*chars) [i] = abc[i];
142 i++;
145 (*chars) [i] = 0;
148 typedef struct {
149 int b;
150 int a;
151 int c;
152 } union_test_1_type;
154 LIBTEST_API int STDCALL
155 mono_union_test_1 (union_test_1_type u1) {
156 // printf ("Got values %d %d %d\n", u1.b, u1.a, u1.c);
157 return u1.a + u1.b + u1.c;
160 LIBTEST_API int STDCALL
161 mono_return_int (int a) {
162 // printf ("Got value %d\n", a);
163 return a;
166 LIBTEST_API float STDCALL
167 mono_test_marshal_pass_return_float (float f) {
168 return f + 1.0;
171 struct ss
173 int i;
176 LIBTEST_API int STDCALL
177 mono_return_int_ss (struct ss a) {
178 // printf ("Got value %d\n", a.i);
179 return a.i;
182 LIBTEST_API struct ss STDCALL
183 mono_return_ss (struct ss a) {
184 // printf ("Got value %d\n", a.i);
185 a.i++;
186 return a;
189 struct sc1
191 char c[1];
194 LIBTEST_API struct sc1 STDCALL
195 mono_return_sc1 (struct sc1 a) {
196 // printf ("Got value %d\n", a.c[0]);
197 a.c[0]++;
198 return a;
202 struct sc3
204 char c[3];
207 LIBTEST_API struct sc3 STDCALL
208 mono_return_sc3 (struct sc3 a) {
209 // printf ("Got values %d %d %d\n", a.c[0], a.c[1], a.c[2]);
210 a.c[0]++;
211 a.c[1] += 2;
212 a.c[2] += 3;
213 return a;
216 struct sc5
218 char c[5];
221 LIBTEST_API struct sc5 STDCALL
222 mono_return_sc5 (struct sc5 a) {
223 // printf ("Got values %d %d %d %d %d\n", a.c[0], a.c[1], a.c[2], a.c[3], a.c[4]);
224 a.c[0]++;
225 a.c[1] += 2;
226 a.c[2] += 3;
227 a.c[3] += 4;
228 a.c[4] += 5;
229 return a;
232 union su
234 int i1;
235 int i2;
238 LIBTEST_API int STDCALL
239 mono_return_int_su (union su a) {
240 // printf ("Got value %d\n", a.i1);
241 return a.i1;
244 LIBTEST_API int STDCALL
245 mono_test_many_int_arguments (int a, int b, int c, int d, int e,
246 int f, int g, int h, int i, int j);
247 LIBTEST_API short STDCALL
248 mono_test_many_short_arguments (short a, short b, short c, short d, short e,
249 short f, short g, short h, short i, short j);
250 LIBTEST_API char STDCALL
251 mono_test_many_char_arguments (char a, char b, char c, char d, char e,
252 char f, char g, char h, char i, char j);
254 LIBTEST_API int STDCALL
255 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)
257 return a + b + c + d + e + f + g + h + i + j;
260 LIBTEST_API short STDCALL
261 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)
263 return a + b + c + d + e + f + g + h + i + j;
266 LIBTEST_API char STDCALL
267 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)
269 return a + b + c + d + e + f + g + h + i + j;
272 LIBTEST_API float STDCALL
273 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)
275 return a + b + c + d + e + f + g + h + i + j;
278 LIBTEST_API double STDCALL
279 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)
281 return a + b + c + d + e + f + g + h + i + j;
284 LIBTEST_API double STDCALL
285 mono_test_split_double_arguments (double a, double b, float c, double d, double e)
287 return a + b + c + d + e;
290 LIBTEST_API int STDCALL
291 mono_test_puts_static (char *s)
293 // printf ("TEST %s\n", s);
294 return 1;
297 typedef int (STDCALL *SimpleDelegate3) (int a, int b);
299 LIBTEST_API int STDCALL
300 mono_invoke_delegate (SimpleDelegate3 delegate)
302 int res;
304 // printf ("start invoke %p\n", delegate);
306 res = delegate (2, 3);
308 // printf ("end invoke\n");
310 return res;
313 LIBTEST_API int STDCALL
314 mono_invoke_simple_delegate (SimpleDelegate d)
316 return d (4);
319 LIBTEST_API int STDCALL
320 mono_test_marshal_char (short a1)
322 if (a1 == 'a')
323 return 0;
325 return 1;
328 LIBTEST_API void STDCALL
329 mono_test_marshal_char_array (gunichar2 *s)
331 const char m[] = "abcdef";
332 gunichar2* s2;
333 glong len;
335 s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
337 len = (len * 2) + 2;
338 memcpy (s, s2, len);
340 g_free (s2);
343 LIBTEST_API int STDCALL
344 mono_test_empty_pinvoke (int i)
346 return i;
349 LIBTEST_API int STDCALL
350 mono_test_marshal_bool_byref (int a, int *b, int c)
352 int res = *b;
354 *b = 1;
356 return res;
359 LIBTEST_API int STDCALL
360 mono_test_marshal_bool_in_as_I1_U1 (char bTrue, char bFalse)
362 if (!bTrue)
363 return 1;
364 if (bFalse)
365 return 2;
366 return 0;
369 LIBTEST_API int STDCALL
370 mono_test_marshal_bool_out_as_I1_U1 (char* bTrue, char* bFalse)
372 if (!bTrue || !bFalse)
373 return 3;
375 *bTrue = 1;
376 *bFalse = 0;
378 return 0;
381 LIBTEST_API int STDCALL
382 mono_test_marshal_bool_ref_as_I1_U1 (char* bTrue, char* bFalse)
384 if (!bTrue || !bFalse)
385 return 4;
387 if (!(*bTrue))
388 return 5;
389 if (*bFalse)
390 return 6;
392 *bFalse = 1;
393 *bTrue = 0;
395 return 0;
398 LIBTEST_API int STDCALL
399 mono_test_marshal_array (int *a1)
401 int i, sum = 0;
403 for (i = 0; i < 50; i++)
404 sum += a1 [i];
406 return sum;
409 LIBTEST_API int STDCALL
410 mono_test_marshal_inout_array (int *a1)
412 int i, sum = 0;
414 for (i = 0; i < 50; i++) {
415 sum += a1 [i];
416 a1 [i] = 50 - a1 [i];
419 return sum;
422 LIBTEST_API int /* cdecl */
423 mono_test_marshal_inout_array_cdecl (int *a1)
425 return mono_test_marshal_inout_array (a1);
428 LIBTEST_API int STDCALL
429 mono_test_marshal_out_array (int *a1)
431 int i;
433 for (i = 0; i < 50; i++) {
434 a1 [i] = i;
437 return 0;
440 LIBTEST_API int STDCALL
441 mono_test_marshal_inout_nonblittable_array (gunichar2 *a1)
443 int i, sum = 0;
445 for (i = 0; i < 10; i++) {
446 a1 [i] = 'F';
449 return sum;
452 typedef struct {
453 int a;
454 int b;
455 int c;
456 const char *d;
457 gunichar2 *d2;
458 } simplestruct;
460 typedef struct {
461 double x;
462 double y;
463 } point;
465 LIBTEST_API simplestruct STDCALL
466 mono_test_return_vtype (int i)
468 simplestruct res;
469 static gunichar2 test2 [] = { 'T', 'E', 'S', 'T', '2', 0 };
471 res.a = 0;
472 res.b = 1;
473 res.c = 0;
474 res.d = "TEST";
475 res.d2 = test2;
477 return res;
480 LIBTEST_API void STDCALL
481 mono_test_delegate_struct (void)
483 // printf ("TEST\n");
486 typedef char* (STDCALL *ReturnStringDelegate) (const char *s);
488 LIBTEST_API char * STDCALL
489 mono_test_return_string (ReturnStringDelegate func)
491 char *res;
493 // printf ("mono_test_return_string\n");
495 res = func ("TEST");
496 marshal_free (res);
498 // printf ("got string: %s\n", res);
499 return marshal_strdup ("12345");
502 typedef int (STDCALL *RefVTypeDelegate) (int a, simplestruct *ss, int b);
504 LIBTEST_API int STDCALL
505 mono_test_ref_vtype (int a, simplestruct *ss, int b, RefVTypeDelegate func)
507 if (a == 1 && b == 2 && ss->a == 0 && ss->b == 1 && ss->c == 0 &&
508 !strcmp (ss->d, "TEST1")) {
509 ss->a = 1;
510 ss->b = 0;
511 ss->c = 1;
512 ss->d = "TEST2";
514 return func (a, ss, b);
517 return 1;
520 typedef int (STDCALL *OutVTypeDelegate) (int a, simplestruct *ss, int b);
522 LIBTEST_API int STDCALL
523 mono_test_marshal_out_struct (int a, simplestruct *ss, int b, OutVTypeDelegate func)
525 /* Check that the input pointer is ignored */
526 ss->d = (gpointer)0x12345678;
528 func (a, ss, b);
530 if (ss->a && ss->b && ss->c && !strcmp (ss->d, "TEST3"))
531 return 0;
532 else
533 return 1;
536 typedef struct {
537 int a;
538 SimpleDelegate func, func2, func3;
539 } DelegateStruct;
541 LIBTEST_API DelegateStruct STDCALL
542 mono_test_marshal_delegate_struct (DelegateStruct ds)
544 DelegateStruct res;
546 res.a = ds.func (ds.a) + ds.func2 (ds.a) + (ds.func3 == NULL ? 0 : 1);
547 res.func = ds.func;
548 res.func2 = ds.func2;
549 res.func3 = NULL;
551 return res;
554 LIBTEST_API int STDCALL
555 mono_test_marshal_struct (simplestruct ss)
557 if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
558 !strcmp (ss.d, "TEST"))
559 return 0;
561 return 1;
564 LIBTEST_API int STDCALL
565 mono_test_marshal_byref_struct (simplestruct *ss, int a, int b, int c, char *d)
567 gboolean res = (ss->a == a && ss->b == b && ss->c == c && strcmp (ss->d, d) == 0);
569 marshal_free ((char*)ss->d);
571 ss->a = !ss->a;
572 ss->b = !ss->b;
573 ss->c = !ss->c;
574 ss->d = marshal_strdup ("DEF");
576 return res ? 0 : 1;
579 typedef struct {
580 int a;
581 int b;
582 int c;
583 char *d;
584 unsigned char e;
585 double f;
586 unsigned char g;
587 guint64 h;
588 } simplestruct2;
590 LIBTEST_API int STDCALL
591 mono_test_marshal_struct2 (simplestruct2 ss)
593 if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
594 !strcmp (ss.d, "TEST") &&
595 ss.e == 99 && ss.f == 1.5 && ss.g == 42 && ss.h == (guint64)123)
596 return 0;
598 return 1;
601 /* on HP some of the struct should be on the stack and not in registers */
602 LIBTEST_API int STDCALL
603 mono_test_marshal_struct2_2 (int i, int j, int k, simplestruct2 ss)
605 if (i != 10 || j != 11 || k != 12)
606 return 1;
607 if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
608 !strcmp (ss.d, "TEST") &&
609 ss.e == 99 && ss.f == 1.5 && ss.g == 42 && ss.h == (guint64)123)
610 return 0;
612 return 1;
615 LIBTEST_API int STDCALL
616 mono_test_marshal_lpstruct (simplestruct *ss)
618 if (ss->a == 0 && ss->b == 1 && ss->c == 0 &&
619 !strcmp (ss->d, "TEST"))
620 return 0;
622 return 1;
625 LIBTEST_API int STDCALL
626 mono_test_marshal_lpstruct_blittable (point *p)
628 if (p->x == 1.0 && p->y == 2.0)
629 return 0;
630 else
631 return 1;
634 LIBTEST_API int STDCALL
635 mono_test_marshal_struct_array (simplestruct2 *ss)
637 if (! (ss[0].a == 0 && ss[0].b == 1 && ss[0].c == 0 &&
638 !strcmp (ss[0].d, "TEST") &&
639 ss[0].e == 99 && ss[0].f == 1.5 && ss[0].g == 42 && ss[0].h == (guint64)123))
640 return 1;
642 if (! (ss[1].a == 0 && ss[1].b == 0 && ss[1].c == 0 &&
643 !strcmp (ss[1].d, "TEST2") &&
644 ss[1].e == 100 && ss[1].f == 2.5 && ss[1].g == 43 && ss[1].h == (guint64)124))
645 return 1;
647 return 0;
650 typedef struct long_align_struct {
651 gint32 a;
652 gint64 b;
653 gint64 c;
654 } long_align_struct;
656 LIBTEST_API int STDCALL
657 mono_test_marshal_long_align_struct_array (long_align_struct *ss)
659 return ss[0].a + ss[0].b + ss[0].c + ss[1].a + ss[1].b + ss[1].c;
662 LIBTEST_API simplestruct2 * STDCALL
663 mono_test_marshal_class (int i, int j, int k, simplestruct2 *ss, int l)
665 simplestruct2 *res;
667 if (!ss)
668 return NULL;
670 if (i != 10 || j != 11 || k != 12 || l != 14)
671 return NULL;
672 if (! (ss->a == 0 && ss->b == 1 && ss->c == 0 &&
673 !strcmp (ss->d, "TEST") &&
674 ss->e == 99 && ss->f == 1.5 && ss->g == 42 && ss->h == (guint64)123))
675 return NULL;
677 res = g_new0 (simplestruct2, 1);
678 memcpy (res, ss, sizeof (simplestruct2));
679 res->d = marshal_strdup ("TEST");
680 return res;
683 LIBTEST_API int STDCALL
684 mono_test_marshal_byref_class (simplestruct2 **ssp)
686 simplestruct2 *ss = *ssp;
687 simplestruct2 *res;
689 if (! (ss->a == 0 && ss->b == 1 && ss->c == 0 &&
690 !strcmp (ss->d, "TEST") &&
691 ss->e == 99 && ss->f == 1.5 && ss->g == 42 && ss->h == (guint64)123))
692 return 1;
694 res = g_new0 (simplestruct2, 1);
695 memcpy (res, ss, sizeof (simplestruct2));
696 res->d = marshal_strdup ("TEST-RES");
698 *ssp = res;
699 return 0;
702 static void *
703 get_sp (void)
705 int i;
706 void *p;
708 /* Yes, this is correct, we are only trying to determine the value of the stack here */
709 p = &i;
710 return p;
713 LIBTEST_API int STDCALL
714 reliable_delegate (int a)
716 return a;
720 * Checks whether get_sp() works as expected. It doesn't work with gcc-2.95.3 on linux.
722 static gboolean
723 is_get_sp_reliable (void)
725 void *sp1, *sp2;
727 reliable_delegate(1);
728 sp1 = get_sp();
729 reliable_delegate(1);
730 sp2 = get_sp();
731 return sp1 == sp2;
734 LIBTEST_API int STDCALL
735 mono_test_marshal_delegate (SimpleDelegate delegate)
737 void *sp1, *sp2;
739 /* Check that the delegate wrapper is stdcall */
740 delegate (2);
741 sp1 = get_sp ();
742 delegate (2);
743 sp2 = get_sp ();
744 if (is_get_sp_reliable())
745 g_assert (sp1 == sp2);
747 return delegate (2);
750 static int STDCALL inc_cb (int i)
752 return i + 1;
755 LIBTEST_API int STDCALL
756 mono_test_marshal_out_delegate (SimpleDelegate *delegate)
758 *delegate = inc_cb;
760 return 0;
763 LIBTEST_API SimpleDelegate STDCALL
764 mono_test_marshal_return_delegate (SimpleDelegate delegate)
766 return delegate;
769 static int STDCALL
770 return_plus_one (int i)
772 return i + 1;
775 LIBTEST_API SimpleDelegate STDCALL
776 mono_test_marshal_return_delegate_2 (void)
778 return return_plus_one;
781 typedef simplestruct (STDCALL *SimpleDelegate2) (simplestruct ss);
783 static gboolean
784 is_utf16_equals (gunichar2 *s1, const char *s2)
786 char *s;
787 int res;
789 s = g_utf16_to_utf8 (s1, -1, NULL, NULL, NULL);
790 res = strcmp (s, s2);
791 g_free (s);
793 return res == 0;
796 LIBTEST_API int STDCALL
797 mono_test_marshal_delegate2 (SimpleDelegate2 delegate)
799 simplestruct ss, res;
801 ss.a = 0;
802 ss.b = 1;
803 ss.c = 0;
804 ss.d = "TEST";
805 ss.d2 = g_utf8_to_utf16 ("TEST2", -1, NULL, NULL, NULL);
807 res = delegate (ss);
808 if (! (res.a && !res.b && res.c && !strcmp (res.d, "TEST-RES") && is_utf16_equals (res.d2, "TEST2-RES")))
809 return 1;
811 return 0;
814 typedef simplestruct* (STDCALL *SimpleDelegate4) (simplestruct *ss);
816 LIBTEST_API int STDCALL
817 mono_test_marshal_delegate4 (SimpleDelegate4 delegate)
819 simplestruct ss;
820 simplestruct *res;
822 ss.a = 0;
823 ss.b = 1;
824 ss.c = 0;
825 ss.d = "TEST";
827 /* Check argument */
828 res = delegate (&ss);
829 if (!res)
830 return 1;
832 /* Check return value */
833 if (! (!res->a && res->b && !res->c && !strcmp (res->d, "TEST")))
834 return 2;
836 /* Check NULL argument and NULL result */
837 res = delegate (NULL);
838 if (res)
839 return 3;
841 return 0;
844 typedef int (STDCALL *SimpleDelegate5) (simplestruct **ss);
846 LIBTEST_API int STDCALL
847 mono_test_marshal_delegate5 (SimpleDelegate5 delegate)
849 simplestruct ss;
850 int res;
851 simplestruct *ptr;
853 ss.a = 0;
854 ss.b = 1;
855 ss.c = 0;
856 ss.d = "TEST";
858 ptr = &ss;
860 res = delegate (&ptr);
861 if (res != 0)
862 return 1;
864 if (!(ptr->a && !ptr->b && ptr->c && !strcmp (ptr->d, "RES")))
865 return 2;
867 return 0;
870 LIBTEST_API int STDCALL
871 mono_test_marshal_delegate6 (SimpleDelegate5 delegate)
873 int res;
875 res = delegate (NULL);
877 return 0;
880 typedef int (STDCALL *SimpleDelegate7) (simplestruct **ss);
882 LIBTEST_API int STDCALL
883 mono_test_marshal_delegate7 (SimpleDelegate7 delegate)
885 int res;
886 simplestruct *ptr;
888 /* Check that the input pointer is ignored */
889 ptr = (gpointer)0x12345678;
891 res = delegate (&ptr);
892 if (res != 0)
893 return 1;
895 if (!(ptr->a && !ptr->b && ptr->c && !strcmp (ptr->d, "RES")))
896 return 2;
898 return 0;
901 typedef int (STDCALL *InOutByvalClassDelegate) (simplestruct *ss);
903 LIBTEST_API int STDCALL
904 mono_test_marshal_inout_byval_class_delegate (InOutByvalClassDelegate delegate)
906 int res;
907 simplestruct ss;
909 ss.a = FALSE;
910 ss.b = TRUE;
911 ss.c = FALSE;
912 ss.d = g_strdup_printf ("%s", "FOO");
914 res = delegate (&ss);
915 if (res != 0)
916 return 1;
918 if (!(ss.a && !ss.b && ss.c && !strcmp (ss.d, "RES")))
919 return 2;
921 return 0;
924 typedef int (STDCALL *SimpleDelegate8) (gunichar2 *s);
926 LIBTEST_API int STDCALL
927 mono_test_marshal_delegate8 (SimpleDelegate8 delegate, gunichar2 *s)
929 return delegate (s);
932 typedef int (STDCALL *return_int_fnt) (int i);
933 typedef int (STDCALL *SimpleDelegate9) (return_int_fnt d);
935 LIBTEST_API int STDCALL
936 mono_test_marshal_delegate9 (SimpleDelegate9 delegate, gpointer ftn)
938 return delegate (ftn);
941 static int STDCALL
942 return_self (int i)
944 return i;
947 LIBTEST_API int STDCALL
948 mono_test_marshal_delegate10 (SimpleDelegate9 delegate)
950 return delegate (return_self);
953 typedef int (STDCALL *PrimitiveByrefDelegate) (int *i);
955 LIBTEST_API int STDCALL
956 mono_test_marshal_primitive_byref_delegate (PrimitiveByrefDelegate delegate)
958 int i = 1;
960 int res = delegate (&i);
961 if (res != 0)
962 return res;
964 if (i != 2)
965 return 2;
967 return 0;
970 typedef int (STDCALL *return_int_delegate) (int i);
972 typedef return_int_delegate (STDCALL *ReturnDelegateDelegate) (void);
974 LIBTEST_API int STDCALL
975 mono_test_marshal_return_delegate_delegate (ReturnDelegateDelegate d)
977 return (d ()) (55);
980 LIBTEST_API int STDCALL
981 mono_test_marshal_stringbuilder (char *s, int n)
983 const char m[] = "This is my message. Isn't it nice?";
985 if (strcmp (s, "ABCD") != 0)
986 return 1;
987 strncpy(s, m, n);
988 s [n] = '\0';
989 return 0;
992 LIBTEST_API int STDCALL
993 mono_test_marshal_stringbuilder_default (char *s, int n)
995 const char m[] = "This is my message. Isn't it nice?";
997 strncpy(s, m, n);
998 s [n] = '\0';
999 return 0;
1002 LIBTEST_API int STDCALL
1003 mono_test_marshal_stringbuilder_unicode (gunichar2 *s, int n)
1005 const char m[] = "This is my message. Isn't it nice?";
1006 gunichar2* s2;
1007 glong len;
1009 s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
1011 len = (len * 2) + 2;
1012 if (len > (n * 2))
1013 len = n * 2;
1014 memcpy (s, s2, len);
1016 g_free (s2);
1018 return 0;
1021 LIBTEST_API void STDCALL
1022 mono_test_marshal_stringbuilder_out (char **s)
1024 const char m[] = "This is my message. Isn't it nice?";
1025 char *str;
1027 str = marshal_alloc (strlen (m) + 1);
1028 memcpy (str, m, strlen (m) + 1);
1030 *s = str;
1033 LIBTEST_API int STDCALL
1034 mono_test_marshal_stringbuilder_out_unicode (gunichar2 **s)
1036 const char m[] = "This is my message. Isn't it nice?";
1037 gunichar2 *s2;
1038 glong len;
1040 s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
1042 len = (len * 2) + 2;
1043 *s = marshal_alloc (len);
1044 memcpy (*s, s2, len);
1046 g_free (s2);
1048 return 0;
1051 typedef struct {
1052 #ifndef __GNUC__
1053 char a;
1054 #endif
1055 } EmptyStruct;
1057 LIBTEST_API int STDCALL
1058 mono_test_marshal_empty_string_array (char **array)
1060 return (array == NULL) ? 0 : 1;
1063 LIBTEST_API int STDCALL
1064 mono_test_marshal_string_array (char **array)
1066 if (strcmp (array [0], "ABC"))
1067 return 1;
1068 if (strcmp (array [1], "DEF"))
1069 return 2;
1071 if (array [2] != NULL)
1072 return 3;
1074 return 0;
1077 LIBTEST_API int STDCALL
1078 mono_test_marshal_byref_string_array (char ***array)
1080 if (*array == NULL)
1081 return 0;
1083 if (strcmp ((*array) [0], "Alpha"))
1084 return 2;
1085 if (strcmp ((*array) [1], "Beta"))
1086 return 2;
1087 if (strcmp ((*array) [2], "Gamma"))
1088 return 2;
1090 return 1;
1093 LIBTEST_API int STDCALL
1094 mono_test_marshal_stringbuilder_array (char **array)
1096 if (strcmp (array [0], "ABC"))
1097 return 1;
1098 if (strcmp (array [1], "DEF"))
1099 return 2;
1101 strcpy (array [0], "DEF");
1102 strcpy (array [1], "ABC");
1104 return 0;
1107 LIBTEST_API int STDCALL
1108 mono_test_marshal_unicode_string_array (gunichar2 **array, char **array2)
1110 GError *error = NULL;
1111 char *s;
1113 s = g_utf16_to_utf8 (array [0], -1, NULL, NULL, &error);
1114 if (strcmp (s, "ABC")) {
1115 g_free (s);
1116 return 1;
1118 else
1119 g_free (s);
1121 s = g_utf16_to_utf8 (array [1], -1, NULL, NULL, &error);
1122 if (strcmp (s, "DEF")) {
1123 g_free (s);
1124 return 2;
1126 else
1127 g_free (s);
1129 if (strcmp (array2 [0], "ABC"))
1130 return 3;
1132 if (strcmp (array2 [1], "DEF"))
1133 return 4;
1135 return 0;
1138 /* this does not work on Redhat gcc 2.96 */
1139 LIBTEST_API int STDCALL
1140 mono_test_empty_struct (int a, EmptyStruct es, int b)
1142 // printf ("mono_test_empty_struct %d %d\n", a, b);
1144 // Intel icc on ia64 passes 'es' in 2 registers
1145 #if defined(__ia64) && defined(__INTEL_COMPILER)
1146 return 0;
1147 #else
1148 if (a == 1 && b == 2)
1149 return 0;
1150 return 1;
1151 #endif
1154 typedef struct {
1155 char a[100];
1156 } ByValStrStruct;
1158 LIBTEST_API ByValStrStruct * STDCALL
1159 mono_test_byvalstr_gen (void)
1161 ByValStrStruct *ret;
1163 ret = malloc(sizeof(ByValStrStruct));
1164 memset(ret, 'a', sizeof(ByValStrStruct)-1);
1165 ret->a[sizeof(ByValStrStruct)-1] = 0;
1167 return ret;
1170 LIBTEST_API int STDCALL
1171 mono_test_byvalstr_check (ByValStrStruct* data, char* correctString)
1173 int ret;
1175 ret = strcmp(data->a, correctString);
1176 // printf ("T1: %s\n", data->a);
1177 // printf ("T2: %s\n", correctString);
1179 /* we need g_free because the allocation was performed by mono_test_byvalstr_gen */
1180 g_free (data);
1181 return (ret != 0);
1184 typedef struct {
1185 guint16 a[4];
1186 int flag;
1187 } ByValStrStruct_Unicode;
1189 LIBTEST_API int STDCALL
1190 mono_test_byvalstr_check_unicode (ByValStrStruct_Unicode *ref, int test)
1192 if (ref->flag != 0x1234abcd){
1193 printf ("overwritten data");
1194 return 1;
1197 if (test == 1 || test == 3){
1198 if (ref->a [0] != '1' ||
1199 ref->a [1] != '2' ||
1200 ref->a [2] != '3')
1201 return 1;
1202 return 0;
1204 if (test == 2){
1205 if (ref->a [0] != '1' ||
1206 ref->a [1] != '2')
1207 return 1;
1208 return 0;
1210 return 10;
1213 LIBTEST_API int STDCALL
1214 NameManglingAnsi (char *data)
1216 return data [0] + data [1] + data [2];
1219 LIBTEST_API int STDCALL
1220 NameManglingAnsiA (char *data)
1222 g_assert_not_reached ();
1225 LIBTEST_API int STDCALL
1226 NameManglingAnsiW (char *data)
1228 g_assert_not_reached ();
1231 LIBTEST_API int STDCALL
1232 NameManglingAnsi2A (char *data)
1234 return data [0] + data [1] + data [2];
1237 LIBTEST_API int STDCALL
1238 NameManglingAnsi2W (char *data)
1240 g_assert_not_reached ();
1243 LIBTEST_API int STDCALL
1244 NameManglingUnicode (char *data)
1246 g_assert_not_reached ();
1249 LIBTEST_API int STDCALL
1250 NameManglingUnicodeW (gunichar2 *data)
1252 return data [0] + data [1] + data [2];
1255 LIBTEST_API int STDCALL
1256 NameManglingUnicode2 (gunichar2 *data)
1258 return data [0] + data [1] + data [2];
1261 LIBTEST_API int STDCALL
1262 NameManglingAutoW (char *data)
1264 #ifdef WIN32
1265 return (data [0] + data [1] + data [2]) == 131 ? 0 : 1;
1266 #else
1267 g_assert_not_reached ();
1268 #endif
1271 LIBTEST_API int STDCALL
1272 NameManglingAuto (char *data)
1274 #ifndef WIN32
1275 return (data [0] + data [1] + data [2]) == 198 ? 0 : 1;
1276 #else
1277 g_assert_not_reached ();
1278 #endif
1281 typedef int (STDCALL *intcharFunc)(const char*);
1283 LIBTEST_API void STDCALL
1284 callFunction (intcharFunc f)
1286 f ("ABC");
1289 typedef struct {
1290 const char* str;
1291 int i;
1292 } SimpleObj;
1294 LIBTEST_API int STDCALL
1295 class_marshal_test0 (SimpleObj *obj1)
1297 // printf ("class_marshal_test0 %s %d\n", obj1->str, obj1->i);
1299 if (strcmp(obj1->str, "T1"))
1300 return -1;
1301 if (obj1->i != 4)
1302 return -2;
1304 return 0;
1307 LIBTEST_API int STDCALL
1308 class_marshal_test4 (SimpleObj *obj1)
1310 if (obj1)
1311 return -1;
1313 return 0;
1316 LIBTEST_API void STDCALL
1317 class_marshal_test1 (SimpleObj **obj1)
1319 SimpleObj *res = malloc (sizeof (SimpleObj));
1321 res->str = marshal_strdup ("ABC");
1322 res->i = 5;
1324 *obj1 = res;
1327 LIBTEST_API int STDCALL
1328 class_marshal_test2 (SimpleObj **obj1)
1330 // printf ("class_marshal_test2 %s %d\n", (*obj1)->str, (*obj1)->i);
1332 if (strcmp((*obj1)->str, "ABC"))
1333 return -1;
1334 if ((*obj1)->i != 5)
1335 return -2;
1337 return 0;
1340 LIBTEST_API int STDCALL
1341 string_marshal_test0 (char *str)
1343 if (strcmp (str, "TEST0"))
1344 return -1;
1346 return 0;
1349 LIBTEST_API void STDCALL
1350 string_marshal_test1 (const char **str)
1352 *str = marshal_strdup ("TEST1");
1355 LIBTEST_API int STDCALL
1356 string_marshal_test2 (char **str)
1358 // printf ("string_marshal_test2 %s\n", *str);
1360 if (strcmp (*str, "TEST1"))
1361 return -1;
1363 return 0;
1366 LIBTEST_API int STDCALL
1367 string_marshal_test3 (char *str)
1369 if (str)
1370 return -1;
1372 return 0;
1375 typedef struct {
1376 int a;
1377 int b;
1378 } BlittableClass;
1380 LIBTEST_API BlittableClass* STDCALL
1381 TestBlittableClass (BlittableClass *vl)
1383 BlittableClass *res;
1385 // printf ("TestBlittableClass %d %d\n", vl->a, vl->b);
1387 if (vl) {
1388 vl->a++;
1389 vl->b++;
1391 res = g_new0 (BlittableClass, 1);
1392 memcpy (res, vl, sizeof (BlittableClass));
1393 } else {
1394 res = g_new0 (BlittableClass, 1);
1395 res->a = 42;
1396 res->b = 43;
1399 return res;
1402 typedef struct OSVERSIONINFO_STRUCT
1404 int a;
1405 int b;
1406 } OSVERSIONINFO_STRUCT;
1408 LIBTEST_API int STDCALL
1409 MyGetVersionEx (OSVERSIONINFO_STRUCT *osvi)
1412 // printf ("GOT %d %d\n", osvi->a, osvi->b);
1414 osvi->a += 1;
1415 osvi->b += 1;
1417 return osvi->a + osvi->b;
1420 LIBTEST_API int STDCALL
1421 BugGetVersionEx (int a, int b, int c, int d, int e, int f, int g, int h, OSVERSIONINFO_STRUCT *osvi)
1424 // printf ("GOT %d %d\n", osvi->a, osvi->b);
1426 osvi->a += 1;
1427 osvi->b += 1;
1429 return osvi->a + osvi->b;
1432 LIBTEST_API int STDCALL
1433 mono_test_marshal_point (point pt)
1435 // printf("point %g %g\n", pt.x, pt.y);
1436 if (pt.x == 1.25 && pt.y == 3.5)
1437 return 0;
1439 return 1;
1442 typedef struct {
1443 int x;
1444 double y;
1445 } mixed_point;
1447 LIBTEST_API int STDCALL
1448 mono_test_marshal_mixed_point (mixed_point pt)
1450 // printf("mixed point %d %g\n", pt.x, pt.y);
1451 if (pt.x == 5 && pt.y == 6.75)
1452 return 0;
1454 return 1;
1457 LIBTEST_API int STDCALL
1458 mono_test_marshal_mixed_point_2 (mixed_point *pt)
1460 if (pt->x != 5 || pt->y != 6.75)
1461 return 1;
1463 pt->x = 10;
1464 pt->y = 12.35;
1466 return 0;
1469 LIBTEST_API int STDCALL
1470 marshal_test_ref_bool(int i, char *b1, short *b2, int *b3)
1472 int res = 1;
1473 if (*b1 != 0 && *b1 != 1)
1474 return 1;
1475 if (*b2 != 0 && *b2 != -1) /* variant_bool */
1476 return 1;
1477 if (*b3 != 0 && *b3 != 1)
1478 return 1;
1479 if (i == ((*b1 << 2) | (-*b2 << 1) | *b3))
1480 res = 0;
1481 *b1 = !*b1;
1482 *b2 = ~*b2;
1483 *b3 = !*b3;
1484 return res;
1487 struct BoolStruct
1489 int i;
1490 char b1;
1491 short b2; /* variant_bool */
1492 int b3;
1495 LIBTEST_API int STDCALL
1496 marshal_test_bool_struct(struct BoolStruct *s)
1498 int res = 1;
1499 if (s->b1 != 0 && s->b1 != 1)
1500 return 1;
1501 if (s->b2 != 0 && s->b2 != -1)
1502 return 1;
1503 if (s->b3 != 0 && s->b3 != 1)
1504 return 1;
1505 if (s->i == ((s->b1 << 2) | (-s->b2 << 1) | s->b3))
1506 res = 0;
1507 s->b1 = !s->b1;
1508 s->b2 = ~s->b2;
1509 s->b3 = !s->b3;
1510 return res;
1513 typedef struct {
1514 gint64 l;
1515 } LongStruct2;
1517 typedef struct {
1518 int i;
1519 LongStruct2 l;
1520 } LongStruct;
1522 LIBTEST_API int STDCALL
1523 mono_test_marshal_long_struct (LongStruct *s)
1525 return s->i + s->l.l;
1528 LIBTEST_API void STDCALL
1529 mono_test_last_error (int err)
1531 #ifdef WIN32
1532 SetLastError (err);
1533 #else
1534 errno = err;
1535 #endif
1538 LIBTEST_API int STDCALL
1539 mono_test_asany (void *ptr, int what)
1541 switch (what) {
1542 case 1:
1543 return (*(int*)ptr == 5) ? 0 : 1;
1544 case 2:
1545 return strcmp (ptr, "ABC") == 0 ? 0 : 1;
1546 case 3: {
1547 simplestruct2 ss = *(simplestruct2*)ptr;
1549 if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
1550 !strcmp (ss.d, "TEST") &&
1551 ss.e == 99 && ss.f == 1.5 && ss.g == 42 && ss.h == (guint64)123)
1552 return 0;
1553 else
1554 return 1;
1556 case 4: {
1557 GError *error = NULL;
1558 char *s;
1560 s = g_utf16_to_utf8 (ptr, -1, NULL, NULL, &error);
1562 if (!s)
1563 return 1;
1565 if (!strcmp (s, "ABC")) {
1566 g_free (s);
1567 return 0;
1569 else {
1570 g_free (s);
1571 return 1;
1574 default:
1575 g_assert_not_reached ();
1578 return 1;
1581 typedef struct
1583 int i;
1584 int j;
1585 int k;
1586 char *s;
1587 } AsAnyStruct;
1589 LIBTEST_API int STDCALL
1590 mono_test_marshal_asany_in (void* ptr)
1592 AsAnyStruct* asAny = ptr;
1593 int res = asAny->i + asAny->j + asAny->k;
1595 return res;
1598 LIBTEST_API int STDCALL
1599 mono_test_marshal_asany_inout (void* ptr)
1601 AsAnyStruct* asAny = ptr;
1602 int res = asAny->i + asAny->j + asAny->k;
1604 marshal_free (asAny->s);
1606 asAny->i = 10;
1607 asAny->j = 20;
1608 asAny->k = 30;
1609 asAny->s = 0;
1611 return res;
1614 LIBTEST_API int STDCALL
1615 mono_test_marshal_asany_out (void* ptr)
1617 AsAnyStruct* asAny = ptr;
1618 int res = asAny->i + asAny->j + asAny->k;
1620 asAny->i = 10;
1621 asAny->j = 20;
1622 asAny->k = 30;
1623 asAny->s = 0;
1625 return res;
1629 * AMD64 marshalling tests.
1632 typedef struct amd64_struct1 {
1633 int i;
1634 int j;
1635 int k;
1636 int l;
1637 } amd64_struct1;
1639 LIBTEST_API amd64_struct1 STDCALL
1640 mono_test_marshal_amd64_pass_return_struct1 (amd64_struct1 s)
1642 s.i ++;
1643 s.j ++;
1644 s.k ++;
1645 s.l ++;
1647 return s;
1650 LIBTEST_API amd64_struct1 STDCALL
1651 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)
1653 s.i ++;
1654 s.j ++;
1655 s.k ++;
1656 s.l += 1 + i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8;
1658 return s;
1661 typedef struct amd64_struct2 {
1662 int i;
1663 int j;
1664 } amd64_struct2;
1666 LIBTEST_API amd64_struct2 STDCALL
1667 mono_test_marshal_amd64_pass_return_struct2 (amd64_struct2 s)
1669 s.i ++;
1670 s.j ++;
1672 return s;
1675 typedef struct amd64_struct3 {
1676 int i;
1677 } amd64_struct3;
1679 LIBTEST_API amd64_struct3 STDCALL
1680 mono_test_marshal_amd64_pass_return_struct3 (amd64_struct3 s)
1682 s.i ++;
1684 return s;
1687 typedef struct amd64_struct4 {
1688 double d1, d2;
1689 } amd64_struct4;
1691 LIBTEST_API amd64_struct4 STDCALL
1692 mono_test_marshal_amd64_pass_return_struct4 (amd64_struct4 s)
1694 s.d1 ++;
1695 s.d2 ++;
1697 return s;
1701 * IA64 marshalling tests.
1703 typedef struct test_struct5 {
1704 float d1, d2;
1705 } test_struct5;
1707 LIBTEST_API test_struct5 STDCALL
1708 mono_test_marshal_ia64_pass_return_struct5 (double d1, double d2, test_struct5 s, int i, double d3, double d4)
1710 s.d1 += d1 + d2 + i;
1711 s.d2 += d3 + d4 + i;
1713 return s;
1716 typedef struct test_struct6 {
1717 double d1, d2;
1718 } test_struct6;
1720 LIBTEST_API test_struct6 STDCALL
1721 mono_test_marshal_ia64_pass_return_struct6 (double d1, double d2, test_struct6 s, int i, double d3, double d4)
1723 s.d1 += d1 + d2 + i;
1724 s.d2 += d3 + d4;
1726 return s;
1729 static guint32 custom_res [2];
1731 LIBTEST_API void* STDCALL
1732 mono_test_marshal_pass_return_custom (int i, guint32 *ptr, int j)
1734 /* ptr will be freed by CleanupNative, so make a copy */
1735 custom_res [0] = 0; /* not allocated by AllocHGlobal */
1736 custom_res [1] = ptr [1];
1738 return &custom_res;
1741 LIBTEST_API int STDCALL
1742 mono_test_marshal_pass_out_custom (int i, guint32 **ptr, int j)
1744 custom_res [0] = 0;
1745 custom_res [1] = i + j + 10;
1747 *ptr = custom_res;
1749 return 0;
1752 LIBTEST_API int STDCALL
1753 mono_test_marshal_pass_inout_custom (int i, guint32 *ptr, int j)
1755 ptr [0] = 0;
1756 ptr [1] = i + ptr [1] + j;
1758 return 0;
1761 LIBTEST_API int STDCALL
1762 mono_test_marshal_pass_out_byval_custom (int i, guint32 *ptr, int j)
1764 return ptr == NULL ? 0 : 1;
1767 LIBTEST_API int STDCALL
1768 mono_test_marshal_pass_byref_custom (int i, guint32 **ptr, int j)
1770 (*ptr)[1] += i + j;
1772 return 0;
1775 LIBTEST_API void* STDCALL
1776 mono_test_marshal_pass_return_custom2 (int i, guint32 *ptr, int j)
1778 g_assert_not_reached ();
1780 return NULL;
1783 LIBTEST_API void* STDCALL
1784 mono_test_marshal_pass_return_custom_null (int i, guint32 *ptr, int j)
1786 g_assert (ptr == NULL);
1788 return NULL;
1791 typedef void *(STDCALL *PassReturnPtrDelegate) (void *ptr);
1793 LIBTEST_API int STDCALL
1794 mono_test_marshal_pass_return_custom_in_delegate (PassReturnPtrDelegate del)
1796 guint32 buf [2];
1797 guint32 res;
1798 guint32 *ptr;
1800 buf [0] = 0;
1801 buf [1] = 10;
1803 ptr = del (&buf);
1805 res = ptr [1];
1807 #ifdef WIN32
1808 /* FIXME: Freed with FreeHGlobal */
1809 #else
1810 g_free (ptr);
1811 #endif
1813 return res;
1816 LIBTEST_API int STDCALL
1817 mono_test_marshal_pass_return_custom_null_in_delegate (PassReturnPtrDelegate del)
1819 void *ptr = del (NULL);
1821 return (ptr == NULL) ? 15 : 0;
1824 typedef void (STDCALL *CustomOutParamDelegate) (void **pptr);
1826 LIBTEST_API int STDCALL
1827 mono_test_marshal_custom_out_param_delegate (CustomOutParamDelegate del)
1829 void* pptr = del;
1831 del (&pptr);
1833 if(pptr != NULL)
1834 return 1;
1836 return 0;
1839 typedef int (STDCALL *ReturnEnumDelegate) (int e);
1841 LIBTEST_API int STDCALL
1842 mono_test_marshal_return_enum_delegate (ReturnEnumDelegate func)
1844 return func (1);
1847 typedef struct {
1848 int a, b, c;
1849 gint64 d;
1850 } BlittableStruct;
1852 typedef BlittableStruct (STDCALL *SimpleDelegate10) (BlittableStruct ss);
1854 LIBTEST_API int STDCALL
1855 mono_test_marshal_blittable_struct_delegate (SimpleDelegate10 delegate)
1857 BlittableStruct ss, res;
1859 ss.a = 1;
1860 ss.b = 2;
1861 ss.c = 3;
1862 ss.d = 55;
1864 res = delegate (ss);
1865 if (! ((res.a == -1) && (res.b == -2) && (res.c == -3) && (res.d == -55)))
1866 return 1;
1868 return 0;
1871 LIBTEST_API int STDCALL
1872 mono_test_stdcall_name_mangling (int a, int b, int c)
1874 return a + b + c;
1878 * PASSING AND RETURNING SMALL STRUCTURES FROM DELEGATES TESTS
1881 typedef struct {
1882 int i;
1883 } SmallStruct1;
1885 typedef SmallStruct1 (STDCALL *SmallStructDelegate1) (SmallStruct1 ss);
1887 LIBTEST_API int STDCALL
1888 mono_test_marshal_small_struct_delegate1 (SmallStructDelegate1 delegate)
1890 SmallStruct1 ss, res;
1892 ss.i = 1;
1894 res = delegate (ss);
1895 if (! (res.i == -1))
1896 return 1;
1898 return 0;
1901 typedef struct {
1902 gint16 i, j;
1903 } SmallStruct2;
1905 typedef SmallStruct2 (STDCALL *SmallStructDelegate2) (SmallStruct2 ss);
1907 LIBTEST_API int STDCALL
1908 mono_test_marshal_small_struct_delegate2 (SmallStructDelegate2 delegate)
1910 SmallStruct2 ss, res;
1912 ss.i = 2;
1913 ss.j = 3;
1915 res = delegate (ss);
1916 if (! ((res.i == -2) && (res.j == -3)))
1917 return 1;
1919 return 0;
1922 typedef struct {
1923 gint16 i;
1924 gint8 j;
1925 } SmallStruct3;
1927 typedef SmallStruct3 (STDCALL *SmallStructDelegate3) (SmallStruct3 ss);
1929 LIBTEST_API int STDCALL
1930 mono_test_marshal_small_struct_delegate3 (SmallStructDelegate3 delegate)
1932 SmallStruct3 ss, res;
1934 ss.i = 1;
1935 ss.j = 2;
1937 res = delegate (ss);
1938 if (! ((res.i == -1) && (res.j == -2)))
1939 return 1;
1941 return 0;
1944 typedef struct {
1945 gint16 i;
1946 } SmallStruct4;
1948 typedef SmallStruct4 (STDCALL *SmallStructDelegate4) (SmallStruct4 ss);
1950 LIBTEST_API int STDCALL
1951 mono_test_marshal_small_struct_delegate4 (SmallStructDelegate4 delegate)
1953 SmallStruct4 ss, res;
1955 ss.i = 1;
1957 res = delegate (ss);
1958 if (! (res.i == -1))
1959 return 1;
1961 return 0;
1964 typedef struct {
1965 gint64 i;
1966 } SmallStruct5;
1968 typedef SmallStruct5 (STDCALL *SmallStructDelegate5) (SmallStruct5 ss);
1970 LIBTEST_API int STDCALL
1971 mono_test_marshal_small_struct_delegate5 (SmallStructDelegate5 delegate)
1973 SmallStruct5 ss, res;
1975 ss.i = 5;
1977 res = delegate (ss);
1978 if (! (res.i == -5))
1979 return 1;
1981 return 0;
1984 typedef struct {
1985 int i, j;
1986 } SmallStruct6;
1988 typedef SmallStruct6 (STDCALL *SmallStructDelegate6) (SmallStruct6 ss);
1990 LIBTEST_API int STDCALL
1991 mono_test_marshal_small_struct_delegate6 (SmallStructDelegate6 delegate)
1993 SmallStruct6 ss, res;
1995 ss.i = 1;
1996 ss.j = 2;
1998 res = delegate (ss);
1999 if (! ((res.i == -1) && (res.j == -2)))
2000 return 1;
2002 return 0;
2005 typedef struct {
2006 int i;
2007 gint16 j;
2008 } SmallStruct7;
2010 typedef SmallStruct7 (STDCALL *SmallStructDelegate7) (SmallStruct7 ss);
2012 LIBTEST_API int STDCALL
2013 mono_test_marshal_small_struct_delegate7 (SmallStructDelegate7 delegate)
2015 SmallStruct7 ss, res;
2017 ss.i = 1;
2018 ss.j = 2;
2020 res = delegate (ss);
2021 if (! ((res.i == -1) && (res.j == -2)))
2022 return 1;
2024 return 0;
2027 typedef struct {
2028 float i;
2029 } SmallStruct8;
2031 typedef SmallStruct8 (STDCALL *SmallStructDelegate8) (SmallStruct8 ss);
2033 LIBTEST_API int STDCALL
2034 mono_test_marshal_small_struct_delegate8 (SmallStructDelegate8 delegate)
2036 SmallStruct8 ss, res;
2038 ss.i = 1.0;
2040 res = delegate (ss);
2041 if (! ((res.i == -1.0)))
2042 return 1;
2044 return 0;
2047 typedef struct {
2048 double i;
2049 } SmallStruct9;
2051 typedef SmallStruct9 (STDCALL *SmallStructDelegate9) (SmallStruct9 ss);
2053 LIBTEST_API int STDCALL
2054 mono_test_marshal_small_struct_delegate9 (SmallStructDelegate9 delegate)
2056 SmallStruct9 ss, res;
2058 ss.i = 1.0;
2060 res = delegate (ss);
2061 if (! ((res.i == -1.0)))
2062 return 1;
2064 return 0;
2067 typedef struct {
2068 float i, j;
2069 } SmallStruct10;
2071 typedef SmallStruct10 (STDCALL *SmallStructDelegate10) (SmallStruct10 ss);
2073 LIBTEST_API int STDCALL
2074 mono_test_marshal_small_struct_delegate10 (SmallStructDelegate10 delegate)
2076 SmallStruct10 ss, res;
2078 ss.i = 1.0;
2079 ss.j = 2.0;
2081 res = delegate (ss);
2082 if (! ((res.i == -1.0) && (res.j == -2.0)))
2083 return 1;
2085 return 0;
2088 typedef struct {
2089 float i;
2090 int j;
2091 } SmallStruct11;
2093 typedef SmallStruct11 (STDCALL *SmallStructDelegate11) (SmallStruct11 ss);
2095 LIBTEST_API int STDCALL
2096 mono_test_marshal_small_struct_delegate11 (SmallStructDelegate11 delegate)
2098 SmallStruct11 ss, res;
2100 ss.i = 1.0;
2101 ss.j = 2;
2103 res = delegate (ss);
2104 if (! ((res.i == -1.0) && (res.j == -2)))
2105 return 1;
2107 return 0;
2110 typedef int (STDCALL *ArrayDelegate) (int i, char *j, void *arr);
2112 LIBTEST_API int STDCALL
2113 mono_test_marshal_array_delegate (void *arr, int len, ArrayDelegate del)
2115 return del (len, NULL, arr);
2118 typedef int (STDCALL *ArrayDelegateLong) (gint64 i, char *j, void *arr);
2120 LIBTEST_API int STDCALL
2121 mono_test_marshal_array_delegate_long (void *arr, gint64 len, ArrayDelegateLong del)
2123 return del (len, NULL, arr);
2126 LIBTEST_API int STDCALL
2127 mono_test_marshal_out_array_delegate (int *arr, int len, ArrayDelegate del)
2129 del (len, NULL, arr);
2131 if ((arr [0] != 1) || (arr [1] != 2))
2132 return 1;
2133 else
2134 return 0;
2137 typedef gunichar2* (STDCALL *UnicodeStringDelegate) (gunichar2 *message);
2139 LIBTEST_API int STDCALL
2140 mono_test_marshal_return_unicode_string_delegate (UnicodeStringDelegate del)
2142 const char m[] = "abcdef";
2143 gunichar2 *s2, *res;
2144 glong len;
2146 s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
2148 res = del (s2);
2150 marshal_free (res);
2152 return 0;
2155 LIBTEST_API int STDCALL
2156 mono_test_marshal_out_string_array_delegate (char **arr, int len, ArrayDelegate del)
2158 del (len, NULL, arr);
2160 if (!strcmp (arr [0], "ABC") && !strcmp (arr [1], "DEF"))
2161 return 0;
2162 else
2163 return 1;
2166 typedef int (*CdeclDelegate) (int i, int j);
2168 LIBTEST_API int STDCALL
2169 mono_test_marshal_cdecl_delegate (CdeclDelegate del)
2171 int i;
2173 for (i = 0; i < 1000; ++i)
2174 del (1, 2);
2176 return 0;
2179 typedef char** (STDCALL *ReturnStringArrayDelegate) (int i);
2181 LIBTEST_API int STDCALL
2182 mono_test_marshal_return_string_array_delegate (ReturnStringArrayDelegate d)
2184 char **arr = d (2);
2185 int res;
2187 if (arr == NULL)
2188 return 3;
2190 if (strcmp (arr [0], "ABC") || strcmp (arr [1], "DEF"))
2191 res = 1;
2192 else
2193 res = 0;
2195 marshal_free (arr);
2197 return res;
2200 typedef int (STDCALL *ByrefStringDelegate) (char **s);
2202 LIBTEST_API int STDCALL
2203 mono_test_marshal_byref_string_delegate (ByrefStringDelegate d)
2205 char *s = (char*)"ABC";
2206 int res;
2208 res = d (&s);
2209 if (res != 0)
2210 return res;
2212 if (!strcmp (s, "DEF"))
2213 res = 0;
2214 else
2215 res = 2;
2217 marshal_free (s);
2219 return res;
2222 LIBTEST_API int STDCALL
2223 add_delegate (int i, int j)
2225 return i + j;
2228 LIBTEST_API gpointer STDCALL
2229 mono_test_marshal_return_fnptr (void)
2231 return &add_delegate;
2234 LIBTEST_API int STDCALL
2235 mono_xr (int code)
2237 printf ("codigo %x\n", code);
2238 return code + 1234;
2241 typedef struct {
2242 int handle;
2243 } HandleRef;
2245 LIBTEST_API HandleRef STDCALL
2246 mono_xr_as_handle (int code)
2248 HandleRef ref;
2250 memset (&ref, 0, sizeof (ref));
2252 return ref;
2255 typedef struct {
2256 int a;
2257 void *handle1;
2258 void *handle2;
2259 int b;
2260 } HandleStructs;
2262 LIBTEST_API int STDCALL
2263 mono_safe_handle_struct_ref (HandleStructs *x)
2265 printf ("Dingus Ref! \n");
2266 printf ("Values: %d %d %p %p\n", x->a, x->b, x->handle1, x->handle2);
2267 if (x->a != 1234)
2268 return 1;
2269 if (x->b != 8743)
2270 return 2;
2272 if (x->handle1 != (void*) 0x7080feed)
2273 return 3;
2275 if (x->handle2 != (void*) 0x1234abcd)
2276 return 4;
2278 return 0xf00d;
2281 LIBTEST_API int STDCALL
2282 mono_safe_handle_struct (HandleStructs x)
2284 printf ("Dingus Standard! \n");
2285 printf ("Values: %d %d %p %p\n", x.a, x.b, x.handle1, x.handle2);
2286 if (x.a != 1234)
2287 return 1;
2288 if (x.b != 8743)
2289 return 2;
2291 if (x.handle1 != (void*) 0x7080feed)
2292 return 3;
2294 if (x.handle2 != (void*) 0x1234abcd)
2295 return 4;
2297 return 0xf00f;
2300 typedef struct {
2301 void *a;
2302 } TrivialHandle;
2304 LIBTEST_API int STDCALL
2305 mono_safe_handle_struct_simple (TrivialHandle x)
2307 printf ("The value is %p\n", x.a);
2308 return ((int)(gsize)x.a) * 2;
2311 LIBTEST_API int STDCALL
2312 mono_safe_handle_return (void)
2314 return 0x1000f00d;
2317 LIBTEST_API void STDCALL
2318 mono_safe_handle_ref (void **handle)
2320 if (*handle != 0){
2321 *handle = (void *) 0xbad;
2322 return;
2325 *handle = (void *) 0x800d;
2328 LIBTEST_API double STDCALL
2329 mono_test_marshal_date_time (double d, double *d2)
2331 *d2 = d;
2332 return d;
2336 * COM INTEROP TESTS
2339 #ifndef WIN32
2341 typedef struct {
2342 guint16 vt;
2343 guint16 wReserved1;
2344 guint16 wReserved2;
2345 guint16 wReserved3;
2346 union {
2347 gint64 llVal;
2348 gint32 lVal;
2349 guint8 bVal;
2350 gint16 iVal;
2351 float fltVal;
2352 double dblVal;
2353 gint16 boolVal;
2354 gunichar2* bstrVal;
2355 gint8 cVal;
2356 guint16 uiVal;
2357 guint32 ulVal;
2358 guint64 ullVal;
2359 struct {
2360 gpointer pvRecord;
2361 gpointer pRecInfo;
2364 } VARIANT;
2366 typedef enum {
2367 VARIANT_TRUE = -1,
2368 VARIANT_FALSE = 0
2369 } VariantBool;
2371 typedef enum {
2372 VT_EMPTY = 0,
2373 VT_NULL = 1,
2374 VT_I2 = 2,
2375 VT_I4 = 3,
2376 VT_R4 = 4,
2377 VT_R8 = 5,
2378 VT_CY = 6,
2379 VT_DATE = 7,
2380 VT_BSTR = 8,
2381 VT_DISPATCH = 9,
2382 VT_ERROR = 10,
2383 VT_BOOL = 11,
2384 VT_VARIANT = 12,
2385 VT_UNKNOWN = 13,
2386 VT_DECIMAL = 14,
2387 VT_I1 = 16,
2388 VT_UI1 = 17,
2389 VT_UI2 = 18,
2390 VT_UI4 = 19,
2391 VT_I8 = 20,
2392 VT_UI8 = 21,
2393 VT_INT = 22,
2394 VT_UINT = 23,
2395 VT_VOID = 24,
2396 VT_HRESULT = 25,
2397 VT_PTR = 26,
2398 VT_SAFEARRAY = 27,
2399 VT_CARRAY = 28,
2400 VT_USERDEFINED = 29,
2401 VT_LPSTR = 30,
2402 VT_LPWSTR = 31,
2403 VT_RECORD = 36,
2404 VT_FILETIME = 64,
2405 VT_BLOB = 65,
2406 VT_STREAM = 66,
2407 VT_STORAGE = 67,
2408 VT_STREAMED_OBJECT = 68,
2409 VT_STORED_OBJECT = 69,
2410 VT_BLOB_OBJECT = 70,
2411 VT_CF = 71,
2412 VT_CLSID = 72,
2413 VT_VECTOR = 4096,
2414 VT_ARRAY = 8192,
2415 VT_BYREF = 16384
2416 } VarEnum;
2418 void VariantInit(VARIANT* vt)
2420 vt->vt = VT_EMPTY;
2423 typedef struct
2425 guint32 a;
2426 guint16 b;
2427 guint16 c;
2428 guint8 d[8];
2429 } GUID;
2431 #define S_OK 0
2433 #endif
2435 LIBTEST_API int STDCALL
2436 mono_test_marshal_bstr_in(gunichar2* bstr)
2438 gint32 result = 0;
2439 gchar* bstr_utf8 = g_utf16_to_utf8 (bstr, -1, NULL, NULL, NULL);
2440 result = strcmp("mono_test_marshal_bstr_in", bstr_utf8);
2441 g_free(bstr_utf8);
2442 if (result == 0)
2443 return 0;
2444 return 1;
2447 LIBTEST_API int STDCALL
2448 mono_test_marshal_bstr_out(gunichar2** bstr)
2450 *bstr = marshal_bstr_alloc ("mono_test_marshal_bstr_out");
2451 return 0;
2454 LIBTEST_API int STDCALL
2455 mono_test_marshal_bstr_in_null(gunichar2* bstr)
2457 if (!bstr)
2458 return 0;
2459 return 1;
2462 LIBTEST_API int STDCALL
2463 mono_test_marshal_bstr_out_null(gunichar2** bstr)
2465 *bstr = NULL;
2466 return 0;
2469 LIBTEST_API int STDCALL
2470 mono_test_marshal_variant_in_sbyte(VARIANT variant)
2472 if (variant.vt == VT_I1 && variant.cVal == 100)
2473 return 0;
2474 return 1;
2477 LIBTEST_API int STDCALL
2478 mono_test_marshal_variant_in_byte(VARIANT variant)
2480 if (variant.vt == VT_UI1 && variant.bVal == 100)
2481 return 0;
2482 return 1;
2485 LIBTEST_API int STDCALL
2486 mono_test_marshal_variant_in_short(VARIANT variant)
2488 if (variant.vt == VT_I2 && variant.iVal == 314)
2489 return 0;
2490 return 1;
2493 LIBTEST_API int STDCALL
2494 mono_test_marshal_variant_in_ushort(VARIANT variant)
2496 if (variant.vt == VT_UI2 && variant.uiVal == 314)
2497 return 0;
2498 return 1;
2501 LIBTEST_API int STDCALL
2502 mono_test_marshal_variant_in_int(VARIANT variant)
2504 if (variant.vt == VT_I4 && variant.lVal == 314)
2505 return 0;
2506 return 1;
2509 LIBTEST_API int STDCALL
2510 mono_test_marshal_variant_in_uint(VARIANT variant)
2512 if (variant.vt == VT_UI4 && variant.ulVal == 314)
2513 return 0;
2514 return 1;
2517 LIBTEST_API int STDCALL
2518 mono_test_marshal_variant_in_long(VARIANT variant)
2520 if (variant.vt == VT_I8 && variant.llVal == 314)
2521 return 0;
2522 return 1;
2525 LIBTEST_API int STDCALL
2526 mono_test_marshal_variant_in_ulong(VARIANT variant)
2528 if (variant.vt == VT_UI8 && variant.ullVal == 314)
2529 return 0;
2530 return 1;
2533 LIBTEST_API int STDCALL
2534 mono_test_marshal_variant_in_float(VARIANT variant)
2536 if (variant.vt == VT_R4 && (variant.fltVal - 3.14)/3.14 < .001)
2537 return 0;
2538 return 1;
2541 LIBTEST_API int STDCALL
2542 mono_test_marshal_variant_in_double(VARIANT variant)
2544 if (variant.vt == VT_R8 && (variant.dblVal - 3.14)/3.14 < .001)
2545 return 0;
2546 return 1;
2549 LIBTEST_API int STDCALL
2550 mono_test_marshal_variant_in_bstr(VARIANT variant)
2552 gint32 result = 0;
2553 gchar* bstr_utf8 = g_utf16_to_utf8 (variant.bstrVal, -1, NULL, NULL, NULL);
2554 result = strcmp("PI", bstr_utf8);
2555 g_free(bstr_utf8);
2557 if (variant.vt == VT_BSTR && !result)
2558 return 0;
2559 return 1;
2562 LIBTEST_API int STDCALL
2563 mono_test_marshal_variant_in_bool_true (VARIANT variant)
2565 if (variant.vt == VT_BOOL && variant.boolVal == VARIANT_TRUE)
2566 return 0;
2567 return 1;
2570 LIBTEST_API int STDCALL
2571 mono_test_marshal_variant_in_bool_false (VARIANT variant)
2573 if (variant.vt == VT_BOOL && variant.boolVal == VARIANT_FALSE)
2574 return 0;
2575 return 1;
2578 LIBTEST_API int STDCALL
2579 mono_test_marshal_variant_out_sbyte(VARIANT* variant)
2581 variant->vt = VT_I1;
2582 variant->cVal = 100;
2584 return 0;
2587 LIBTEST_API int STDCALL
2588 mono_test_marshal_variant_out_byte(VARIANT* variant)
2590 variant->vt = VT_UI1;
2591 variant->bVal = 100;
2593 return 0;
2596 LIBTEST_API int STDCALL
2597 mono_test_marshal_variant_out_short(VARIANT* variant)
2599 variant->vt = VT_I2;
2600 variant->iVal = 314;
2602 return 0;
2605 LIBTEST_API int STDCALL
2606 mono_test_marshal_variant_out_ushort(VARIANT* variant)
2608 variant->vt = VT_UI2;
2609 variant->uiVal = 314;
2611 return 0;
2614 LIBTEST_API int STDCALL
2615 mono_test_marshal_variant_out_int(VARIANT* variant)
2617 variant->vt = VT_I4;
2618 variant->lVal = 314;
2620 return 0;
2623 LIBTEST_API int STDCALL
2624 mono_test_marshal_variant_out_uint(VARIANT* variant)
2626 variant->vt = VT_UI4;
2627 variant->ulVal = 314;
2629 return 0;
2632 LIBTEST_API int STDCALL
2633 mono_test_marshal_variant_out_long(VARIANT* variant)
2635 variant->vt = VT_I8;
2636 variant->llVal = 314;
2638 return 0;
2641 LIBTEST_API int STDCALL
2642 mono_test_marshal_variant_out_ulong(VARIANT* variant)
2644 variant->vt = VT_UI8;
2645 variant->ullVal = 314;
2647 return 0;
2650 LIBTEST_API int STDCALL
2651 mono_test_marshal_variant_out_float(VARIANT* variant)
2653 variant->vt = VT_R4;
2654 variant->fltVal = 3.14;
2656 return 0;
2659 LIBTEST_API int STDCALL
2660 mono_test_marshal_variant_out_double(VARIANT* variant)
2662 variant->vt = VT_R8;
2663 variant->dblVal = 3.14;
2665 return 0;
2668 LIBTEST_API int STDCALL
2669 mono_test_marshal_variant_out_bstr(VARIANT* variant)
2671 variant->vt = VT_BSTR;
2672 variant->bstrVal = marshal_bstr_alloc("PI");
2674 return 0;
2677 LIBTEST_API int STDCALL
2678 mono_test_marshal_variant_out_bool_true (VARIANT* variant)
2680 variant->vt = VT_BOOL;
2681 variant->boolVal = VARIANT_TRUE;
2683 return 0;
2686 LIBTEST_API int STDCALL
2687 mono_test_marshal_variant_out_bool_false (VARIANT* variant)
2689 variant->vt = VT_BOOL;
2690 variant->boolVal = VARIANT_FALSE;
2692 return 0;
2695 typedef int (STDCALL *VarFunc) (int vt, VARIANT variant);
2696 typedef int (STDCALL *VarRefFunc) (int vt, VARIANT* variant);
2698 LIBTEST_API int STDCALL
2699 mono_test_marshal_variant_in_sbyte_unmanaged(VarFunc func)
2701 VARIANT vt;
2702 vt.vt = VT_I1;
2703 vt.cVal = -100;
2704 return func (VT_I1, vt);
2707 LIBTEST_API int STDCALL
2708 mono_test_marshal_variant_in_byte_unmanaged(VarFunc func)
2710 VARIANT vt;
2711 vt.vt = VT_UI1;
2712 vt.bVal = 100;
2713 return func (VT_UI1, vt);
2716 LIBTEST_API int STDCALL
2717 mono_test_marshal_variant_in_short_unmanaged(VarFunc func)
2719 VARIANT vt;
2720 vt.vt = VT_I2;
2721 vt.iVal = -100;
2722 return func (VT_I2, vt);
2725 LIBTEST_API int STDCALL
2726 mono_test_marshal_variant_in_ushort_unmanaged(VarFunc func)
2728 VARIANT vt;
2729 vt.vt = VT_UI2;
2730 vt.uiVal = 100;
2731 return func (VT_UI2, vt);
2734 LIBTEST_API int STDCALL
2735 mono_test_marshal_variant_in_int_unmanaged(VarFunc func)
2737 VARIANT vt;
2738 vt.vt = VT_I4;
2739 vt.lVal = -100;
2740 return func (VT_I4, vt);
2743 LIBTEST_API int STDCALL
2744 mono_test_marshal_variant_in_uint_unmanaged(VarFunc func)
2746 VARIANT vt;
2747 vt.vt = VT_UI4;
2748 vt.ulVal = 100;
2749 return func (VT_UI4, vt);
2752 LIBTEST_API int STDCALL
2753 mono_test_marshal_variant_in_long_unmanaged(VarFunc func)
2755 VARIANT vt;
2756 vt.vt = VT_I8;
2757 vt.llVal = -100;
2758 return func (VT_I8, vt);
2761 LIBTEST_API int STDCALL
2762 mono_test_marshal_variant_in_ulong_unmanaged(VarFunc func)
2764 VARIANT vt;
2765 vt.vt = VT_UI8;
2766 vt.ullVal = 100;
2767 return func (VT_UI8, vt);
2770 LIBTEST_API int STDCALL
2771 mono_test_marshal_variant_in_float_unmanaged(VarFunc func)
2773 VARIANT vt;
2774 vt.vt = VT_R4;
2775 vt.fltVal = 3.14;
2776 return func (VT_R4, vt);
2779 LIBTEST_API int STDCALL
2780 mono_test_marshal_variant_in_double_unmanaged(VarFunc func)
2782 VARIANT vt;
2783 vt.vt = VT_R8;
2784 vt.dblVal = 3.14;
2785 return func (VT_R8, vt);
2788 LIBTEST_API int STDCALL
2789 mono_test_marshal_variant_in_bstr_unmanaged(VarFunc func)
2791 VARIANT vt;
2792 vt.vt = VT_BSTR;
2793 vt.bstrVal = marshal_bstr_alloc("PI");
2794 return func (VT_BSTR, vt);
2797 LIBTEST_API int STDCALL
2798 mono_test_marshal_variant_in_bool_true_unmanaged(VarFunc func)
2800 VARIANT vt;
2801 vt.vt = VT_BOOL;
2802 vt.boolVal = VARIANT_TRUE;
2803 return func (VT_BOOL, vt);
2806 LIBTEST_API int STDCALL
2807 mono_test_marshal_variant_in_bool_false_unmanaged(VarFunc func)
2809 VARIANT vt;
2810 vt.vt = VT_BOOL;
2811 vt.boolVal = VARIANT_FALSE;
2812 return func (VT_BOOL, vt);
2815 LIBTEST_API int STDCALL
2816 mono_test_marshal_variant_out_sbyte_unmanaged(VarRefFunc func)
2818 VARIANT vt;
2819 VariantInit (&vt);
2820 func (VT_I1, &vt);
2821 if (vt.vt == VT_I1 && vt.cVal == -100)
2822 return 0;
2823 return 1;
2826 LIBTEST_API int STDCALL
2827 mono_test_marshal_variant_out_byte_unmanaged(VarRefFunc func)
2829 VARIANT vt;
2830 VariantInit (&vt);
2831 func (VT_UI1, &vt);
2832 if (vt.vt == VT_UI1 && vt.bVal == 100)
2833 return 0;
2834 return 1;
2837 LIBTEST_API int STDCALL
2838 mono_test_marshal_variant_out_short_unmanaged(VarRefFunc func)
2840 VARIANT vt;
2841 VariantInit (&vt);
2842 func (VT_I2, &vt);
2843 if (vt.vt == VT_I2 && vt.iVal == -100)
2844 return 0;
2845 return 1;
2848 LIBTEST_API int STDCALL
2849 mono_test_marshal_variant_out_ushort_unmanaged(VarRefFunc func)
2851 VARIANT vt;
2852 VariantInit (&vt);
2853 func (VT_UI2, &vt);
2854 if (vt.vt == VT_UI2 && vt.uiVal == 100)
2855 return 0;
2856 return 1;
2859 LIBTEST_API int STDCALL
2860 mono_test_marshal_variant_out_int_unmanaged(VarRefFunc func)
2862 VARIANT vt;
2863 VariantInit (&vt);
2864 func (VT_I4, &vt);
2865 if (vt.vt == VT_I4 && vt.lVal == -100)
2866 return 0;
2867 return 1;
2870 LIBTEST_API int STDCALL
2871 mono_test_marshal_variant_out_uint_unmanaged(VarRefFunc func)
2873 VARIANT vt;
2874 VariantInit (&vt);
2875 func (VT_UI4, &vt);
2876 if (vt.vt == VT_UI4 && vt.ulVal == 100)
2877 return 0;
2878 return 1;
2881 LIBTEST_API int STDCALL
2882 mono_test_marshal_variant_out_long_unmanaged(VarRefFunc func)
2884 VARIANT vt;
2885 VariantInit (&vt);
2886 func (VT_I8, &vt);
2887 if (vt.vt == VT_I8 && vt.llVal == -100)
2888 return 0;
2889 return 1;
2892 LIBTEST_API int STDCALL
2893 mono_test_marshal_variant_out_ulong_unmanaged(VarRefFunc func)
2895 VARIANT vt;
2896 VariantInit (&vt);
2897 func (VT_UI8, &vt);
2898 if (vt.vt == VT_UI8 && vt.ullVal == 100)
2899 return 0;
2900 return 1;
2903 LIBTEST_API int STDCALL
2904 mono_test_marshal_variant_out_float_unmanaged(VarRefFunc func)
2906 VARIANT vt;
2907 VariantInit (&vt);
2908 func (VT_R4, &vt);
2909 if (vt.vt == VT_R4 && fabs (vt.fltVal - 3.14f) < 1e-10)
2910 return 0;
2911 return 1;
2914 LIBTEST_API int STDCALL
2915 mono_test_marshal_variant_out_double_unmanaged(VarRefFunc func)
2917 VARIANT vt;
2918 VariantInit (&vt);
2919 func (VT_R8, &vt);
2920 if (vt.vt == VT_R8 && fabs (vt.dblVal - 3.14) < 1e-10)
2921 return 0;
2922 return 1;
2925 LIBTEST_API int STDCALL
2926 mono_test_marshal_variant_out_bstr_unmanaged(VarRefFunc func)
2928 VARIANT vt;
2929 gchar* bstr_utf8;
2930 gint32 result = 0;
2933 VariantInit (&vt);
2934 func (VT_BSTR, &vt);
2935 bstr_utf8 = g_utf16_to_utf8 (vt.bstrVal, -1, NULL, NULL, NULL);
2936 result = strcmp("PI", bstr_utf8);
2937 g_free(bstr_utf8);
2938 if (vt.vt == VT_BSTR && !result)
2939 return 0;
2940 return 1;
2943 LIBTEST_API int STDCALL
2944 mono_test_marshal_variant_out_bool_true_unmanaged(VarRefFunc func)
2946 VARIANT vt;
2947 VariantInit (&vt);
2948 func (VT_BOOL, &vt);
2949 if (vt.vt == VT_BOOL && vt.boolVal == VARIANT_TRUE)
2950 return 0;
2951 return 1;
2954 LIBTEST_API int STDCALL
2955 mono_test_marshal_variant_out_bool_false_unmanaged(VarRefFunc func)
2957 VARIANT vt;
2958 VariantInit (&vt);
2959 func (VT_BOOL, &vt);
2960 if (vt.vt == VT_BOOL && vt.boolVal == VARIANT_TRUE)
2961 return 0;
2962 return 1;
2965 typedef struct MonoComObject MonoComObject;
2967 typedef struct
2969 int (STDCALL *QueryInterface)(MonoComObject* pUnk, gpointer riid, gpointer* ppv);
2970 int (STDCALL *AddRef)(MonoComObject* pUnk);
2971 int (STDCALL *Release)(MonoComObject* pUnk);
2972 int (STDCALL *get_ITest)(MonoComObject* pUnk, MonoComObject* *ppUnk);
2973 int (STDCALL *SByteIn)(MonoComObject* pUnk, char a);
2974 int (STDCALL *ByteIn)(MonoComObject* pUnk, unsigned char a);
2975 int (STDCALL *ShortIn)(MonoComObject* pUnk, short a);
2976 int (STDCALL *UShortIn)(MonoComObject* pUnk, unsigned short a);
2977 int (STDCALL *IntIn)(MonoComObject* pUnk, int a);
2978 int (STDCALL *UIntIn)(MonoComObject* pUnk, unsigned int a);
2979 int (STDCALL *LongIn)(MonoComObject* pUnk, gint64 a);
2980 int (STDCALL *ULongIn)(MonoComObject* pUnk, guint64 a);
2981 int (STDCALL *FloatIn)(MonoComObject* pUnk, float a);
2982 int (STDCALL *DoubleIn)(MonoComObject* pUnk, double a);
2983 int (STDCALL *ITestIn)(MonoComObject* pUnk, MonoComObject* pUnk2);
2984 int (STDCALL *ITestOut)(MonoComObject* pUnk, MonoComObject* *ppUnk);
2985 } MonoIUnknown;
2987 struct MonoComObject
2989 MonoIUnknown* vtbl;
2990 int m_ref;
2993 static GUID IID_ITest = {0, 0, 0, {0,0,0,0,0,0,0,1}};
2994 static GUID IID_IMonoUnknown = {0, 0, 0, {0xc0,0,0,0,0,0,0,0x46}};
2995 static GUID IID_IMonoDispatch = {0x00020400, 0, 0, {0xc0,0,0,0,0,0,0,0x46}};
2997 LIBTEST_API int STDCALL
2998 MonoQueryInterface(MonoComObject* pUnk, gpointer riid, gpointer* ppv)
3001 *ppv = NULL;
3002 if (!memcmp(riid, &IID_IMonoUnknown, sizeof(GUID))) {
3003 *ppv = pUnk;
3004 return S_OK;
3006 else if (!memcmp(riid, &IID_ITest, sizeof(GUID))) {
3007 *ppv = pUnk;
3008 return S_OK;
3010 else if (!memcmp(riid, &IID_IMonoDispatch, sizeof(GUID))) {
3011 *ppv = pUnk;
3012 return S_OK;
3014 return 0x80004002; //E_NOINTERFACE;
3017 LIBTEST_API int STDCALL
3018 MonoAddRef(MonoComObject* pUnk)
3020 return ++(pUnk->m_ref);
3023 LIBTEST_API int STDCALL
3024 MonoRelease(MonoComObject* pUnk)
3026 return --(pUnk->m_ref);
3029 LIBTEST_API int STDCALL
3030 SByteIn(MonoComObject* pUnk, char a)
3032 return S_OK;
3035 LIBTEST_API int STDCALL
3036 ByteIn(MonoComObject* pUnk, unsigned char a)
3038 return S_OK;
3041 LIBTEST_API int STDCALL
3042 ShortIn(MonoComObject* pUnk, short a)
3044 return S_OK;
3047 LIBTEST_API int STDCALL
3048 UShortIn(MonoComObject* pUnk, unsigned short a)
3050 return S_OK;
3053 LIBTEST_API int STDCALL
3054 IntIn(MonoComObject* pUnk, int a)
3056 return S_OK;
3059 LIBTEST_API int STDCALL
3060 UIntIn(MonoComObject* pUnk, unsigned int a)
3062 return S_OK;
3065 LIBTEST_API int STDCALL
3066 LongIn(MonoComObject* pUnk, gint64 a)
3068 return S_OK;
3071 LIBTEST_API int STDCALL
3072 ULongIn(MonoComObject* pUnk, guint64 a)
3074 return S_OK;
3077 LIBTEST_API int STDCALL
3078 FloatIn(MonoComObject* pUnk, float a)
3080 return S_OK;
3083 LIBTEST_API int STDCALL
3084 DoubleIn(MonoComObject* pUnk, double a)
3086 return S_OK;
3089 LIBTEST_API int STDCALL
3090 ITestIn(MonoComObject* pUnk, MonoComObject *pUnk2)
3092 return S_OK;
3095 LIBTEST_API int STDCALL
3096 ITestOut(MonoComObject* pUnk, MonoComObject* *ppUnk)
3098 return S_OK;
3101 LIBTEST_API int STDCALL
3102 get_ITest(MonoComObject* pUnk, MonoComObject* *ppUnk)
3104 return S_OK;
3107 static void create_com_object (MonoComObject** pOut)
3109 *pOut = g_new0 (MonoComObject, 1);
3110 (*pOut)->vtbl = g_new0 (MonoIUnknown, 1);
3112 (*pOut)->m_ref = 1;
3113 (*pOut)->vtbl->QueryInterface = MonoQueryInterface;
3114 (*pOut)->vtbl->AddRef = MonoAddRef;
3115 (*pOut)->vtbl->Release = MonoRelease;
3116 (*pOut)->vtbl->SByteIn = SByteIn;
3117 (*pOut)->vtbl->ByteIn = ByteIn;
3118 (*pOut)->vtbl->ShortIn = ShortIn;
3119 (*pOut)->vtbl->UShortIn = UShortIn;
3120 (*pOut)->vtbl->IntIn = IntIn;
3121 (*pOut)->vtbl->UIntIn = UIntIn;
3122 (*pOut)->vtbl->LongIn = LongIn;
3123 (*pOut)->vtbl->ULongIn = ULongIn;
3124 (*pOut)->vtbl->FloatIn = FloatIn;
3125 (*pOut)->vtbl->DoubleIn = DoubleIn;
3126 (*pOut)->vtbl->ITestIn = ITestIn;
3127 (*pOut)->vtbl->ITestOut = ITestOut;
3128 (*pOut)->vtbl->get_ITest = get_ITest;
3131 static MonoComObject* same_object = NULL;
3133 LIBTEST_API int STDCALL
3134 mono_test_marshal_com_object_create(MonoComObject* *pUnk)
3136 create_com_object (pUnk);
3138 if (!same_object)
3139 same_object = *pUnk;
3141 return 0;
3144 LIBTEST_API int STDCALL
3145 mono_test_marshal_com_object_same(MonoComObject* *pUnk)
3147 *pUnk = same_object;
3149 return 0;
3152 LIBTEST_API int STDCALL
3153 mono_test_marshal_com_object_destroy(MonoComObject *pUnk)
3155 int ref = --(pUnk->m_ref);
3156 g_free(pUnk->vtbl);
3157 g_free(pUnk);
3159 return ref;
3162 LIBTEST_API int STDCALL
3163 mono_test_marshal_com_object_ref_count(MonoComObject *pUnk)
3165 return pUnk->m_ref;
3168 LIBTEST_API int STDCALL
3169 mono_test_marshal_ccw_itest (MonoComObject *pUnk)
3171 int hr = 0;
3172 MonoComObject* pTest;
3174 if (!pUnk)
3175 return 1;
3177 hr = pUnk->vtbl->SByteIn (pUnk, -100);
3178 if (hr != 0)
3179 return 2;
3180 hr = pUnk->vtbl->ByteIn (pUnk, 100);
3181 if (hr != 0)
3182 return 3;
3183 hr = pUnk->vtbl->ShortIn (pUnk, -100);
3184 if (hr != 0)
3185 return 4;
3186 hr = pUnk->vtbl->UShortIn (pUnk, 100);
3187 if (hr != 0)
3188 return 5;
3189 hr = pUnk->vtbl->IntIn (pUnk, -100);
3190 if (hr != 0)
3191 return 6;
3192 hr = pUnk->vtbl->UIntIn (pUnk, 100);
3193 if (hr != 0)
3194 return 7;
3195 hr = pUnk->vtbl->LongIn (pUnk, -100);
3196 if (hr != 0)
3197 return 8;
3198 hr = pUnk->vtbl->ULongIn (pUnk, 100);
3199 if (hr != 0)
3200 return 9;
3201 hr = pUnk->vtbl->FloatIn (pUnk, 3.14f);
3202 if (hr != 0)
3203 return 10;
3204 hr = pUnk->vtbl->DoubleIn (pUnk, 3.14);
3205 if (hr != 0)
3206 return 11;
3207 hr = pUnk->vtbl->ITestIn (pUnk, pUnk);
3208 if (hr != 0)
3209 return 12;
3210 hr = pUnk->vtbl->ITestOut (pUnk, &pTest);
3211 if (hr != 0)
3212 return 13;
3214 return 0;
3218 * mono_method_get_unmanaged_thunk tests
3221 #if defined(__GNUC__) && ((defined(__i386__) && (defined(__linux__) || defined (__APPLE__)) || defined (__FreeBSD__) || defined(__OpenBSD__)) || (defined(__ppc__) && defined(__APPLE__)))
3222 #define ALIGN(size) __attribute__ ((aligned(size)))
3223 #else
3224 #define ALIGN(size)
3225 #endif
3228 /* thunks.cs:TestStruct */
3229 typedef struct _TestStruct {
3230 int A;
3231 double B ALIGN(8); /* align according to mono's struct layout */
3232 } TestStruct;
3234 /* Searches for mono symbols in all loaded modules */
3235 static gpointer
3236 lookup_mono_symbol (const char *symbol_name)
3238 gpointer symbol;
3239 if (g_module_symbol (g_module_open (NULL, G_MODULE_BIND_LAZY), symbol_name, &symbol))
3240 return symbol;
3241 else
3242 return NULL;
3245 LIBTEST_API gpointer STDCALL
3246 mono_test_marshal_lookup_symbol (const char *symbol_name)
3248 return lookup_mono_symbol (symbol_name);
3252 * test_method_thunk:
3254 * @test_id: the test number
3255 * @test_method_handle: MonoMethod* of the C# test method
3256 * @create_object_method_handle: MonoMethod* of thunks.cs:Test.CreateObject
3258 LIBTEST_API int STDCALL
3259 test_method_thunk (int test_id, gpointer test_method_handle, gpointer create_object_method_handle)
3261 gpointer (*mono_method_get_unmanaged_thunk)(gpointer)
3262 = lookup_mono_symbol ("mono_method_get_unmanaged_thunk");
3264 gpointer (*mono_string_new_wrapper)(const char *)
3265 = lookup_mono_symbol ("mono_string_new_wrapper");
3267 char* (*mono_string_to_utf8)(gpointer)
3268 = lookup_mono_symbol ("mono_string_to_utf8");
3270 gpointer (*mono_object_unbox)(gpointer)
3271 = lookup_mono_symbol ("mono_object_unbox");
3273 gpointer test_method, ex = NULL;
3274 gpointer (STDCALL *CreateObject)(gpointer*);
3277 if (!mono_method_get_unmanaged_thunk)
3278 return 1;
3280 test_method = mono_method_get_unmanaged_thunk (test_method_handle);
3281 if (!test_method)
3282 return 2;
3284 CreateObject = mono_method_get_unmanaged_thunk (create_object_method_handle);
3285 if (!CreateObject)
3286 return 3;
3289 switch (test_id) {
3291 case 0: {
3292 /* thunks.cs:Test.Test0 */
3293 void (STDCALL *F)(gpointer*) = test_method;
3294 F (&ex);
3295 break;
3298 case 1: {
3299 /* thunks.cs:Test.Test1 */
3300 int (STDCALL *F)(gpointer*) = test_method;
3301 if (F (&ex) != 42)
3302 return 4;
3303 break;
3306 case 2: {
3307 /* thunks.cs:Test.Test2 */
3308 gpointer (STDCALL *F)(gpointer, gpointer*) = test_method;
3309 gpointer str = mono_string_new_wrapper ("foo");
3310 if (str != F (str, &ex))
3311 return 4;
3312 break;
3315 case 3: {
3316 /* thunks.cs:Test.Test3 */
3317 gpointer (STDCALL *F)(gpointer, gpointer, gpointer*);
3318 gpointer obj;
3319 gpointer str;
3321 F = test_method;
3322 obj = CreateObject (&ex);
3323 str = mono_string_new_wrapper ("bar");
3325 if (str != F (obj, str, &ex))
3326 return 4;
3327 break;
3330 case 4: {
3331 /* thunks.cs:Test.Test4 */
3332 int (STDCALL *F)(gpointer, gpointer, int, gpointer*);
3333 gpointer obj;
3334 gpointer str;
3336 F = test_method;
3337 obj = CreateObject (&ex);
3338 str = mono_string_new_wrapper ("bar");
3340 if (42 != F (obj, str, 42, &ex))
3341 return 4;
3343 break;
3346 case 5: {
3347 /* thunks.cs:Test.Test5 */
3348 int (STDCALL *F)(gpointer, gpointer, int, gpointer*);
3349 gpointer obj;
3350 gpointer str;
3352 F = test_method;
3353 obj = CreateObject (&ex);
3354 str = mono_string_new_wrapper ("bar");
3356 F (obj, str, 42, &ex);
3357 if (!ex)
3358 return 4;
3360 break;
3363 case 6: {
3364 /* thunks.cs:Test.Test6 */
3365 int (STDCALL *F)(gpointer, guint8, gint16, gint32, gint64, float, double,
3366 gpointer, gpointer*);
3367 gpointer obj;
3368 gpointer str = mono_string_new_wrapper ("Test6");
3369 int res;
3371 F = test_method;
3372 obj = CreateObject (&ex);
3374 res = F (obj, 254, 32700, -245378, 6789600, 3.1415, 3.1415, str, &ex);
3375 if (ex)
3376 return 4;
3378 if (!res)
3379 return 5;
3381 break;
3384 case 7: {
3385 /* thunks.cs:Test.Test7 */
3386 gint64 (STDCALL *F)(gpointer*) = test_method;
3387 if (F (&ex) != G_MAXINT64)
3388 return 4;
3389 break;
3392 case 8: {
3393 /* thunks.cs:Test.Test8 */
3394 void (STDCALL *F)(guint8*, gint16*, gint32*, gint64*, float*, double*,
3395 gpointer*, gpointer*);
3397 guint8 a1;
3398 gint16 a2;
3399 gint32 a3;
3400 gint64 a4;
3401 float a5;
3402 double a6;
3403 gpointer a7;
3405 F = test_method;
3407 F (&a1, &a2, &a3, &a4, &a5, &a6, &a7, &ex);
3408 if (ex)
3409 return 4;
3411 if (!(a1 == 254 &&
3412 a2 == 32700 &&
3413 a3 == -245378 &&
3414 a4 == 6789600 &&
3415 (fabs (a5 - 3.1415) < 0.001) &&
3416 (fabs (a6 - 3.1415) < 0.001) &&
3417 strcmp (mono_string_to_utf8 (a7), "Test8") == 0))
3418 return 5;
3420 break;
3423 case 9: {
3424 /* thunks.cs:Test.Test9 */
3425 void (STDCALL *F)(guint8*, gint16*, gint32*, gint64*, float*, double*,
3426 gpointer*, gpointer*);
3428 guint8 a1;
3429 gint16 a2;
3430 gint32 a3;
3431 gint64 a4;
3432 float a5;
3433 double a6;
3434 gpointer a7;
3436 F = test_method;
3438 F (&a1, &a2, &a3, &a4, &a5, &a6, &a7, &ex);
3439 if (!ex)
3440 return 4;
3442 break;
3445 case 10: {
3446 /* thunks.cs:Test.Test10 */
3447 void (STDCALL *F)(gpointer*, gpointer*);
3449 gpointer obj1, obj2;
3451 obj1 = obj2 = CreateObject (&ex);
3452 if (ex)
3453 return 4;
3455 F = test_method;
3457 F (&obj1, &ex);
3458 if (ex)
3459 return 5;
3461 if (obj1 == obj2)
3462 return 6;
3464 break;
3467 case 100: {
3468 /* thunks.cs:TestStruct.Test0 */
3469 int (STDCALL *F)(gpointer*, gpointer*);
3471 gpointer obj;
3472 TestStruct *a1;
3473 int res;
3475 obj = CreateObject (&ex);
3476 if (ex)
3477 return 4;
3479 if (!obj)
3480 return 5;
3482 a1 = mono_object_unbox (obj);
3483 if (!a1)
3484 return 6;
3486 a1->A = 42;
3487 a1->B = 3.1415;
3489 F = test_method;
3491 res = F (obj, &ex);
3492 if (ex)
3493 return 7;
3495 if (!res)
3496 return 8;
3498 /* check whether the call was really by value */
3499 if (a1->A != 42 || a1->B != 3.1415)
3500 return 9;
3502 break;
3505 case 101: {
3506 /* thunks.cs:TestStruct.Test1 */
3507 void (STDCALL *F)(gpointer, gpointer*);
3509 TestStruct *a1;
3510 gpointer obj;
3512 obj = CreateObject (&ex);
3513 if (ex)
3514 return 4;
3516 if (!obj)
3517 return 5;
3519 a1 = mono_object_unbox (obj);
3520 if (!a1)
3521 return 6;
3523 F = test_method;
3525 F (obj, &ex);
3526 if (ex)
3527 return 7;
3529 if (a1->A != 42)
3530 return 8;
3532 if (!fabs (a1->B - 3.1415) < 0.001)
3533 return 9;
3535 break;
3538 case 102: {
3539 /* thunks.cs:TestStruct.Test2 */
3540 gpointer (STDCALL *F)(gpointer*);
3542 TestStruct *a1;
3543 gpointer obj;
3545 F = test_method;
3547 obj = F (&ex);
3548 if (ex)
3549 return 4;
3551 if (!obj)
3552 return 5;
3554 a1 = mono_object_unbox (obj);
3556 if (a1->A != 42)
3557 return 5;
3559 if (!fabs (a1->B - 3.1415) < 0.001)
3560 return 6;
3562 break;
3565 case 103: {
3566 /* thunks.cs:TestStruct.Test3 */
3567 void (STDCALL *F)(gpointer, gpointer*);
3569 TestStruct *a1;
3570 gpointer obj;
3572 obj = CreateObject (&ex);
3573 if (ex)
3574 return 4;
3576 if (!obj)
3577 return 5;
3579 a1 = mono_object_unbox (obj);
3581 if (!a1)
3582 return 6;
3584 a1->A = 42;
3585 a1->B = 3.1415;
3587 F = test_method;
3589 F (obj, &ex);
3590 if (ex)
3591 return 4;
3593 if (a1->A != 1)
3594 return 5;
3596 if (a1->B != 17)
3597 return 6;
3599 break;
3602 default:
3603 return 9;
3607 return 0;
3610 typedef struct
3612 char a;
3613 } winx64_struct1;
3615 LIBTEST_API int STDCALL
3616 mono_test_Winx64_struct1_in (winx64_struct1 var)
3618 if (var.a != 123)
3619 return 1;
3620 return 0;
3623 typedef struct
3625 char a;
3626 char b;
3627 } winx64_struct2;
3629 LIBTEST_API int STDCALL
3630 mono_test_Winx64_struct2_in (winx64_struct2 var)
3632 if (var.a != 4)
3633 return 1;
3634 if (var.b != 5)
3635 return 2;
3636 return 0;
3640 typedef struct
3642 char a;
3643 char b;
3644 short c;
3645 } winx64_struct3;
3647 LIBTEST_API int STDCALL
3648 mono_test_Winx64_struct3_in (winx64_struct3 var)
3650 if (var.a != 4)
3651 return 1;
3652 if (var.b != 5)
3653 return 2;
3654 if (var.c != 0x1234)
3655 return 3;
3656 return 0;
3659 typedef struct
3661 char a;
3662 char b;
3663 short c;
3664 unsigned int d;
3665 } winx64_struct4;
3667 LIBTEST_API int STDCALL
3668 mono_test_Winx64_struct4_in (winx64_struct4 var)
3670 if (var.a != 4)
3671 return 1;
3672 if (var.b != 5)
3673 return 2;
3674 if (var.c != 0x1234)
3675 return 3;
3676 if (var.d != 0x87654321)
3677 return 4;
3678 return 0;
3681 typedef struct
3683 char a;
3684 char b;
3685 char c;
3686 } winx64_struct5;
3688 LIBTEST_API int STDCALL
3689 mono_test_Winx64_struct5_in (winx64_struct5 var)
3691 if (var.a != 4)
3692 return 1;
3693 if (var.b != 5)
3694 return 2;
3695 if (var.c != 6)
3696 return 3;
3697 return 0;
3700 typedef struct
3702 winx64_struct1 a;
3703 short b;
3704 char c;
3705 } winx64_struct6;
3707 LIBTEST_API int STDCALL
3708 mono_test_Winx64_struct6_in (winx64_struct6 var)
3710 if (var.a.a != 4)
3711 return 1;
3712 if (var.b != 5)
3713 return 2;
3714 if (var.c != 6)
3715 return 3;
3716 return 0;
3719 LIBTEST_API int STDCALL
3720 mono_test_Winx64_structs_in1 (winx64_struct1 var1,
3721 winx64_struct2 var2,
3722 winx64_struct3 var3,
3723 winx64_struct4 var4)
3725 if (var1.a != 123)
3726 return 1;
3728 if (var2.a != 4)
3729 return 2;
3730 if (var2.b != 5)
3731 return 3;
3733 if (var3.a != 4)
3734 return 4;
3735 if (var3.b != 5)
3736 return 2;
3737 if (var3.c != 0x1234)
3738 return 5;
3740 if (var4.a != 4)
3741 return 6;
3742 if (var4.b != 5)
3743 return 7;
3744 if (var4.c != 0x1234)
3745 return 8;
3746 if (var4.d != 0x87654321)
3747 return 9;
3748 return 0;
3751 LIBTEST_API int STDCALL
3752 mono_test_Winx64_structs_in2 (winx64_struct1 var1,
3753 winx64_struct1 var2,
3754 winx64_struct1 var3,
3755 winx64_struct1 var4,
3756 winx64_struct1 var5)
3758 if (var1.a != 1)
3759 return 1;
3760 if (var2.a != 2)
3761 return 2;
3762 if (var3.a != 3)
3763 return 3;
3764 if (var4.a != 4)
3765 return 4;
3766 if (var5.a != 5)
3767 return 5;
3769 return 0;
3772 LIBTEST_API int STDCALL
3773 mono_test_Winx64_structs_in3 (winx64_struct1 var1,
3774 winx64_struct5 var2,
3775 winx64_struct1 var3,
3776 winx64_struct5 var4,
3777 winx64_struct1 var5,
3778 winx64_struct5 var6)
3780 if (var1.a != 1)
3781 return 1;
3783 if (var2.a != 2)
3784 return 2;
3785 if (var2.b != 3)
3786 return 2;
3787 if (var2.c != 4)
3788 return 4;
3790 if (var3.a != 5)
3791 return 5;
3793 if (var4.a != 6)
3794 return 6;
3795 if (var4.b != 7)
3796 return 7;
3797 if (var4.c != 8)
3798 return 8;
3800 if (var5.a != 9)
3801 return 9;
3803 if (var6.a != 10)
3804 return 10;
3805 if (var6.b != 11)
3806 return 11;
3807 if (var6.c != 12)
3808 return 12;
3810 return 0;
3813 LIBTEST_API winx64_struct1 STDCALL
3814 mono_test_Winx64_struct1_ret (void)
3816 winx64_struct1 ret;
3817 ret.a = 123;
3818 return ret;
3821 LIBTEST_API winx64_struct2 STDCALL
3822 mono_test_Winx64_struct2_ret (void)
3824 winx64_struct2 ret;
3825 ret.a = 4;
3826 ret.b = 5;
3827 return ret;
3830 LIBTEST_API winx64_struct3 STDCALL
3831 mono_test_Winx64_struct3_ret (void)
3833 winx64_struct3 ret;
3834 ret.a = 4;
3835 ret.b = 5;
3836 ret.c = 0x1234;
3837 return ret;
3840 LIBTEST_API winx64_struct4 STDCALL
3841 mono_test_Winx64_struct4_ret (void)
3843 winx64_struct4 ret;
3844 ret.a = 4;
3845 ret.b = 5;
3846 ret.c = 0x1234;
3847 ret.d = 0x87654321;
3848 return ret;
3851 LIBTEST_API winx64_struct5 STDCALL
3852 mono_test_Winx64_struct5_ret (void)
3854 winx64_struct5 ret;
3855 ret.a = 4;
3856 ret.b = 5;
3857 ret.c = 6;
3858 return ret;
3861 LIBTEST_API winx64_struct1 STDCALL
3862 mono_test_Winx64_struct1_ret_5_args (char a, char b, char c, char d, char e)
3864 winx64_struct1 ret;
3865 ret.a = a + b + c + d + e;
3866 return ret;
3869 LIBTEST_API winx64_struct5 STDCALL
3870 mono_test_Winx64_struct5_ret6_args (char a, char b, char c, char d, char e)
3872 winx64_struct5 ret;
3873 ret.a = a + b;
3874 ret.b = c + d;
3875 ret.c = e;
3876 return ret;
3879 typedef struct
3881 float a;
3882 float b;
3883 } winx64_floatStruct;
3885 LIBTEST_API int STDCALL
3886 mono_test_Winx64_floatStruct (winx64_floatStruct a)
3888 if (a.a > 5.6 || a.a < 5.4)
3889 return 1;
3891 if (a.b > 9.6 || a.b < 9.4)
3892 return 2;
3894 return 0;
3897 typedef struct
3899 double a;
3900 } winx64_doubleStruct;
3902 LIBTEST_API int STDCALL
3903 mono_test_Winx64_doubleStruct (winx64_doubleStruct a)
3905 if (a.a > 5.6 || a.a < 5.4)
3906 return 1;
3908 return 0;
3911 typedef int (STDCALL *managed_struct1_delegate) (winx64_struct1 a);
3913 LIBTEST_API int STDCALL
3914 mono_test_managed_Winx64_struct1_in(managed_struct1_delegate func)
3916 winx64_struct1 val;
3917 val.a = 5;
3918 return func (val);
3921 typedef int (STDCALL *managed_struct5_delegate) (winx64_struct5 a);
3923 LIBTEST_API int STDCALL
3924 mono_test_managed_Winx64_struct5_in(managed_struct5_delegate func)
3926 winx64_struct5 val;
3927 val.a = 5;
3928 val.b = 0x10;
3929 val.c = 0x99;
3930 return func (val);
3933 typedef int (STDCALL *managed_struct1_struct5_delegate) (winx64_struct1 a, winx64_struct5 b,
3934 winx64_struct1 c, winx64_struct5 d,
3935 winx64_struct1 e, winx64_struct5 f);
3937 LIBTEST_API int STDCALL
3938 mono_test_managed_Winx64_struct1_struct5_in(managed_struct1_struct5_delegate func)
3940 winx64_struct1 a, c, e;
3941 winx64_struct5 b, d, f;
3942 a.a = 1;
3943 b.a = 2; b.b = 3; b.c = 4;
3944 c.a = 5;
3945 d.a = 6; d.b = 7; d.c = 8;
3946 e.a = 9;
3947 f.a = 10; f.b = 11; f.c = 12;
3949 return func (a, b, c, d, e, f);
3952 typedef winx64_struct1 (STDCALL *managed_struct1_ret_delegate) (void);
3954 LIBTEST_API int STDCALL
3955 mono_test_Winx64_struct1_ret_managed (managed_struct1_ret_delegate func)
3957 winx64_struct1 ret;
3959 ret = func ();
3961 if (ret.a != 0x45)
3962 return 1;
3964 return 0;
3967 typedef winx64_struct5 (STDCALL *managed_struct5_ret_delegate) (void);
3969 LIBTEST_API int STDCALL
3970 mono_test_Winx64_struct5_ret_managed (managed_struct5_ret_delegate func)
3972 winx64_struct5 ret;
3974 ret = func ();
3976 if (ret.a != 0x12)
3977 return 1;
3978 if (ret.b != 0x34)
3979 return 2;
3980 if (ret.c != 0x56)
3981 return 3;
3983 return 0;
3986 LIBTEST_API int STDCALL
3987 mono_test_marshal_bool_in (int arg, unsigned int expected, unsigned int bDefaultMarsh, unsigned int bBoolCustMarsh,
3988 char bI1CustMarsh, unsigned char bU1CustMarsh, short bVBCustMarsh)
3990 switch (arg) {
3991 case 1:
3992 if (bDefaultMarsh != expected)
3993 return 1;
3994 break;
3995 case 2:
3996 if (bBoolCustMarsh != expected)
3997 return 2;
3998 break;
3999 case 3:
4000 if (bI1CustMarsh != expected)
4001 return 3;
4002 break;
4003 case 4:
4004 if (bU1CustMarsh != expected)
4005 return 4;
4006 break;
4007 case 5:
4008 if (bVBCustMarsh != expected)
4009 return 5;
4010 break;
4011 default:
4012 return 999;
4014 return 0;
4017 LIBTEST_API int STDCALL
4018 mono_test_marshal_bool_out (int arg, unsigned int testVal, unsigned int* bDefaultMarsh, unsigned int* bBoolCustMarsh,
4019 char* bI1CustMarsh, unsigned char* bU1CustMarsh, unsigned short* bVBCustMarsh)
4021 switch (arg) {
4022 case 1:
4023 if (!bDefaultMarsh)
4024 return 1;
4025 *bDefaultMarsh = testVal;
4026 break;
4027 case 2:
4028 if (!bBoolCustMarsh)
4029 return 2;
4030 *bBoolCustMarsh = testVal;
4031 break;
4032 case 3:
4033 if (!bI1CustMarsh)
4034 return 3;
4035 *bI1CustMarsh = (char)testVal;
4036 break;
4037 case 4:
4038 if (!bU1CustMarsh)
4039 return 4;
4040 *bU1CustMarsh = (unsigned char)testVal;
4041 break;
4042 case 5:
4043 if (!bVBCustMarsh)
4044 return 5;
4045 *bVBCustMarsh = (unsigned short)testVal;
4046 break;
4047 default:
4048 return 999;
4050 return 0;
4053 LIBTEST_API int STDCALL
4054 mono_test_marshal_bool_ref (int arg, unsigned int expected, unsigned int testVal, unsigned int* bDefaultMarsh,
4055 unsigned int* bBoolCustMarsh, char* bI1CustMarsh, unsigned char* bU1CustMarsh,
4056 unsigned short* bVBCustMarsh)
4058 switch (arg) {
4059 case 1:
4060 if (!bDefaultMarsh)
4061 return 1;
4062 if (*bDefaultMarsh != expected)
4063 return 2;
4064 *bDefaultMarsh = testVal;
4065 break;
4066 case 2:
4067 if (!bBoolCustMarsh)
4068 return 3;
4069 if (*bBoolCustMarsh != expected)
4070 return 4;
4071 *bBoolCustMarsh = testVal;
4072 break;
4073 case 3:
4074 if (!bI1CustMarsh)
4075 return 5;
4076 if (*bI1CustMarsh != expected)
4077 return 6;
4078 *bI1CustMarsh = (char)testVal;
4079 break;
4080 case 4:
4081 if (!bU1CustMarsh)
4082 return 7;
4083 if (*bU1CustMarsh != expected)
4084 return 8;
4085 *bU1CustMarsh = (unsigned char)testVal;
4086 break;
4087 case 5:
4088 if (!bVBCustMarsh)
4089 return 9;
4090 if (*bVBCustMarsh != expected)
4091 return 10;
4092 *bVBCustMarsh = (unsigned short)testVal;
4093 break;
4094 default:
4095 return 999;
4097 return 0;
4101 typedef int (STDCALL *MarshalBoolInDelegate) (int arg, unsigned int expected, unsigned int bDefaultMarsh,
4102 unsigned int bBoolCustMarsh, char bI1CustMarsh, unsigned char bU1CustMarsh, unsigned short bVBCustMarsh);
4104 LIBTEST_API int STDCALL
4105 mono_test_managed_marshal_bool_in (int arg, unsigned int expected, unsigned int testVal, MarshalBoolInDelegate pfcn)
4107 if (!pfcn)
4108 return 0x9900;
4110 switch (arg) {
4111 case 1:
4112 return pfcn (arg, expected, testVal, 0, 0, 0, 0);
4113 case 2:
4114 return pfcn (arg, expected, 0, testVal, 0, 0, 0);
4115 case 3:
4116 return pfcn (arg, expected, 0, 0, testVal, 0, 0);
4117 case 4:
4118 return pfcn (arg, expected, 0, 0, 0, testVal, 0);
4119 case 5:
4120 return pfcn (arg, expected, 0, 0, 0, 0, testVal);
4121 default:
4122 return 0x9800;
4125 return 0;
4128 typedef int (STDCALL *MarshalBoolOutDelegate) (int arg, unsigned int expected, unsigned int* bDefaultMarsh,
4129 unsigned int* bBoolCustMarsh, char* bI1CustMarsh, unsigned char* bU1CustMarsh, unsigned short* bVBCustMarsh);
4131 LIBTEST_API int STDCALL
4132 mono_test_managed_marshal_bool_out (int arg, unsigned int expected, unsigned int testVal, MarshalBoolOutDelegate pfcn)
4134 int ret;
4135 unsigned int lDefaultMarsh, lBoolCustMarsh;
4136 char lI1CustMarsh = 0;
4137 unsigned char lU1CustMarsh = 0;
4138 unsigned short lVBCustMarsh = 0;
4139 lDefaultMarsh = lBoolCustMarsh = 0;
4141 if (!pfcn)
4142 return 0x9900;
4144 switch (arg) {
4145 case 1: {
4146 unsigned int ltVal = 0;
4147 ret = pfcn (arg, testVal, &ltVal, &lBoolCustMarsh, &lI1CustMarsh, &lU1CustMarsh, &lVBCustMarsh);
4148 if (ret)
4149 return 0x0100 + ret;
4150 if (expected != ltVal)
4151 return 0x0200;
4152 break;
4154 case 2: {
4155 unsigned int ltVal = 0;
4156 ret = pfcn (arg, testVal, &lDefaultMarsh, &ltVal, &lI1CustMarsh, &lU1CustMarsh, &lVBCustMarsh);
4157 if (ret)
4158 return 0x0300 + ret;
4159 if (expected != ltVal)
4160 return 0x0400;
4161 break;
4163 case 3: {
4164 char ltVal = 0;
4165 ret = pfcn (arg, testVal, &lDefaultMarsh, &lBoolCustMarsh, &ltVal, &lU1CustMarsh, &lVBCustMarsh);
4166 if (ret)
4167 return 0x0500 + ret;
4168 if (expected != ltVal)
4169 return 0x0600;
4170 break;
4172 case 4: {
4173 unsigned char ltVal = 0;
4174 ret = pfcn (arg, testVal, &lDefaultMarsh, &lBoolCustMarsh, &lI1CustMarsh, &ltVal, &lVBCustMarsh);
4175 if (ret)
4176 return 0x0700 + ret;
4177 if (expected != ltVal)
4178 return 0x0800;
4179 break;
4181 case 5: {
4182 unsigned short ltVal = 0;
4183 ret = pfcn (arg, testVal, &lDefaultMarsh, &lBoolCustMarsh, &lI1CustMarsh, &lU1CustMarsh, &ltVal);
4184 if (ret)
4185 return 0x0900 + ret;
4186 if (expected != ltVal)
4187 return 0x1000;
4188 break;
4190 default:
4191 return 0x9800;
4194 return 0;
4197 typedef int (STDCALL *MarshalBoolRefDelegate) (int arg, unsigned int expected, unsigned int testVal, unsigned int* bDefaultMarsh,
4198 unsigned int* bBoolCustMarsh, char* bI1CustMarsh, unsigned char* bU1CustMarsh, unsigned short* bVBCustMarsh);
4200 LIBTEST_API int STDCALL
4201 mono_test_managed_marshal_bool_ref (int arg, unsigned int expected, unsigned int testVal, unsigned int outExpected,
4202 unsigned int outTestVal, MarshalBoolRefDelegate pfcn)
4204 int ret;
4205 unsigned int lDefaultMarsh, lBoolCustMarsh;
4206 char lI1CustMarsh = 0;
4207 unsigned char lU1CustMarsh = 0;
4208 unsigned short lVBCustMarsh = 0;
4209 lDefaultMarsh = lBoolCustMarsh = 0;
4211 if (!pfcn)
4212 return 0x9900;
4214 switch (arg) {
4215 case 1:
4217 unsigned int ltestVal = testVal;
4218 ret = pfcn (arg, expected, outTestVal, &ltestVal, &lBoolCustMarsh, &lI1CustMarsh, &lU1CustMarsh, &lVBCustMarsh);
4219 if (ret)
4220 return 0x0100 + ret;
4221 if (outExpected != ltestVal)
4222 return 0x0200;
4223 break;
4225 case 2:
4227 unsigned int ltestVal = testVal;
4228 ret = pfcn (arg, expected, outTestVal, &lDefaultMarsh, &ltestVal, &lI1CustMarsh, &lU1CustMarsh, &lVBCustMarsh);
4229 if (ret)
4230 return 0x0300 + ret;
4231 if (outExpected != ltestVal)
4232 return 0x0400;
4233 break;
4235 case 3:
4237 char ltestVal = testVal;
4238 ret = pfcn (arg, expected, outTestVal, &lDefaultMarsh, &lBoolCustMarsh, &ltestVal, &lU1CustMarsh, &lVBCustMarsh);
4239 if (ret)
4240 return 0x0500 + ret;
4241 if (outExpected != ltestVal)
4242 return 0x0600;
4243 break;
4245 case 4:
4247 unsigned char ltestVal = testVal;
4248 ret = pfcn (arg, expected, outTestVal, &lDefaultMarsh, &lBoolCustMarsh, &lI1CustMarsh, &ltestVal, &lVBCustMarsh);
4249 if (ret)
4250 return 0x0700 + ret;
4251 if (outExpected != ltestVal)
4252 return 0x0800;
4253 break;
4255 case 5:
4257 unsigned short ltestVal = testVal;
4258 ret = pfcn (arg, expected, outTestVal, &lDefaultMarsh, &lBoolCustMarsh, &lI1CustMarsh, &lU1CustMarsh, &ltestVal);
4259 if (ret)
4260 return 0x0900 + ret;
4261 if (outExpected != ltestVal)
4262 return 0x1000;
4263 break;
4265 default:
4266 return 0x9800;
4269 return 0;
4272 #ifdef WIN32
4274 LIBTEST_API int STDCALL
4275 mono_test_marshal_safearray_out_1dim_vt_bstr_empty (SAFEARRAY** safearray)
4277 /* Create an empty one-dimensional array of variants */
4278 SAFEARRAY *pSA;
4279 SAFEARRAYBOUND dimensions [1];
4281 dimensions [0].lLbound = 0;
4282 dimensions [0].cElements = 0;
4284 pSA= SafeArrayCreate (VT_VARIANT, 1, dimensions);
4285 *safearray = pSA;
4286 return S_OK;
4289 LIBTEST_API int STDCALL
4290 mono_test_marshal_safearray_out_1dim_vt_bstr (SAFEARRAY** safearray)
4292 /* Create a one-dimensional array of 10 variants filled with "0" to "9" */
4293 SAFEARRAY *pSA;
4294 SAFEARRAYBOUND dimensions [1];
4295 long i;
4296 gchar buffer [20];
4297 HRESULT hr = S_OK;
4298 long indices [1];
4300 dimensions [0].lLbound = 0;
4301 dimensions [0].cElements = 10;
4303 pSA= SafeArrayCreate (VT_VARIANT, 1, dimensions);
4304 for (i= dimensions [0].lLbound; i< (dimensions [0].cElements + dimensions [0].lLbound); i++) {
4305 VARIANT vOut;
4306 VariantInit (&vOut);
4307 vOut.vt = VT_BSTR;
4308 _ltoa (i,buffer,10);
4309 vOut.bstrVal= marshal_bstr_alloc (buffer);
4310 indices [0] = i;
4311 if ((hr = SafeArrayPutElement (pSA, indices, &vOut)) != S_OK) {
4312 VariantClear (&vOut);
4313 SafeArrayDestroy (pSA);
4314 return hr;
4316 VariantClear (&vOut);
4318 *safearray = pSA;
4319 return hr;
4322 LIBTEST_API int STDCALL
4323 mono_test_marshal_safearray_out_2dim_vt_i4 (SAFEARRAY** safearray)
4325 /* Create a two-dimensional array of 4x3 variants filled with 11, 12, 13, etc. */
4326 SAFEARRAY *pSA;
4327 SAFEARRAYBOUND dimensions [2];
4328 long i, j;
4329 HRESULT hr = S_OK;
4330 long indices [2];
4332 dimensions [0].lLbound = 0;
4333 dimensions [0].cElements = 4;
4334 dimensions [1].lLbound = 0;
4335 dimensions [1].cElements = 3;
4337 pSA= SafeArrayCreate(VT_VARIANT, 2, dimensions);
4338 for (i= dimensions [0].lLbound; i< (dimensions [0].cElements + dimensions [0].lLbound); i++) {
4339 for (j= dimensions [1].lLbound; j< (dimensions [1].cElements + dimensions [1].lLbound); j++) {
4340 VARIANT vOut;
4341 VariantInit (&vOut);
4342 vOut.vt = VT_I4;
4343 vOut.lVal = (i+1)*10+(j+1);
4344 indices [0] = i;
4345 indices [1] = j;
4346 if ((hr = SafeArrayPutElement (pSA, indices, &vOut)) != S_OK) {
4347 VariantClear (&vOut);
4348 SafeArrayDestroy (pSA);
4349 return hr;
4351 VariantClear (&vOut); // does a deep destroy of source VARIANT
4354 *safearray = pSA;
4355 return hr;
4358 LIBTEST_API int STDCALL
4359 mono_test_marshal_safearray_out_4dim_vt_i4 (SAFEARRAY** safearray)
4361 /* Create a four-dimensional array of 10x3x6x7 variants filled with their indices */
4362 /* Also use non zero lower bounds */
4363 SAFEARRAY *pSA;
4364 SAFEARRAYBOUND dimensions [4];
4365 long i;
4366 HRESULT hr = S_OK;
4367 VARIANT *pData;
4369 dimensions [0].lLbound = 15;
4370 dimensions [0].cElements = 10;
4371 dimensions [1].lLbound = 20;
4372 dimensions [1].cElements = 3;
4373 dimensions [2].lLbound = 5;
4374 dimensions [2].cElements = 6;
4375 dimensions [3].lLbound = 12;
4376 dimensions [3].cElements = 7;
4378 pSA= SafeArrayCreate (VT_VARIANT, 4, dimensions);
4380 SafeArrayAccessData (pSA, (void **)&pData);
4382 for (i= 0; i< 10*3*6*7; i++) {
4383 VariantInit(&pData [i]);
4384 pData [i].vt = VT_I4;
4385 pData [i].lVal = i;
4387 SafeArrayUnaccessData (pSA);
4388 *safearray = pSA;
4389 return hr;
4392 LIBTEST_API int STDCALL
4393 mono_test_marshal_safearray_in_byval_1dim_empty (SAFEARRAY* safearray)
4395 /* Check that array is one dimensional and empty */
4397 UINT dim;
4398 long lbound, ubound;
4400 dim = SafeArrayGetDim (safearray);
4401 if (dim != 1)
4402 return 1;
4404 SafeArrayGetLBound (safearray, 1, &lbound);
4405 SafeArrayGetUBound (safearray, 1, &ubound);
4407 if ((lbound > 0) || (ubound > 0))
4408 return 1;
4410 return 0;
4413 LIBTEST_API int STDCALL
4414 mono_test_marshal_safearray_in_byval_1dim_vt_i4 (SAFEARRAY* safearray)
4416 /* Check that array is one dimensional containing integers from 1 to 10 */
4418 UINT dim;
4419 long lbound, ubound;
4420 VARIANT *pData;
4421 long i;
4422 int result=0;
4424 dim = SafeArrayGetDim (safearray);
4425 if (dim != 1)
4426 return 1;
4428 SafeArrayGetLBound (safearray, 1, &lbound);
4429 SafeArrayGetUBound (safearray, 1, &ubound);
4431 if ((lbound != 0) || (ubound != 9))
4432 return 1;
4434 SafeArrayAccessData (safearray, (void **)&pData);
4435 for (i= lbound; i <= ubound; i++) {
4436 if ((VariantChangeType (&pData [i], &pData [i], VARIANT_NOUSEROVERRIDE, VT_I4) != S_OK) || (pData [i].lVal != i + 1))
4437 result = 1;
4439 SafeArrayUnaccessData (safearray);
4441 return result;
4444 LIBTEST_API int STDCALL
4445 mono_test_marshal_safearray_in_byval_1dim_vt_mixed (SAFEARRAY* safearray)
4447 /* Check that array is one dimensional containing integers mixed with strings from 0 to 12 */
4449 UINT dim;
4450 long lbound, ubound;
4451 VARIANT *pData;
4452 long i;
4453 long indices [1];
4454 VARIANT element;
4455 int result=0;
4457 VariantInit (&element);
4459 dim = SafeArrayGetDim (safearray);
4460 if (dim != 1)
4461 return 1;
4463 SafeArrayGetLBound (safearray, 1, &lbound);
4464 SafeArrayGetUBound (safearray, 1, &ubound);
4466 if ((lbound != 0) || (ubound != 12))
4467 return 1;
4469 SafeArrayAccessData (safearray, (void **)&pData);
4470 for (i= lbound; i <= ubound; i++) {
4471 if ((i%2 == 0) && (pData [i].vt != VT_I4))
4472 result = 1;
4473 if ((i%2 == 1) && (pData [i].vt != VT_BSTR))
4474 result = 1;
4475 if ((VariantChangeType (&pData [i], &pData [i], VARIANT_NOUSEROVERRIDE, VT_I4) != S_OK) || (pData [i].lVal != i))
4476 result = 1;
4478 SafeArrayUnaccessData (safearray);
4480 /* Change the first element of the array to verify that [in] parameters are not marshalled back to the managed side */
4482 indices [0] = 0;
4483 element.vt = VT_I4;
4484 element.lVal = 333;
4485 SafeArrayPutElement (safearray, indices, &element);
4486 VariantClear (&element);
4488 return result;
4491 LIBTEST_API int STDCALL
4492 mono_test_marshal_safearray_in_byval_2dim_vt_i4 (SAFEARRAY* safearray)
4494 /* Check that array is one dimensional containing integers mixed with strings from 0 to 12 */
4496 UINT dim;
4497 long lbound1, ubound1, lbound2, ubound2;
4498 long i, j, failed;
4499 long indices [2];
4500 VARIANT element;
4502 VariantInit (&element);
4504 dim = SafeArrayGetDim (safearray);
4505 if (dim != 2)
4506 return 1;
4508 SafeArrayGetLBound (safearray, 1, &lbound1);
4509 SafeArrayGetUBound (safearray, 1, &ubound1);
4511 if ((lbound1 != 0) || (ubound1 != 1))
4512 return 1;
4514 SafeArrayGetLBound (safearray, 2, &lbound2);
4515 SafeArrayGetUBound (safearray, 2, &ubound2);
4517 if ((lbound2 != 0) || (ubound2 != 3)) {
4518 return 1;
4521 for (i= lbound1; i <= ubound1; i++) {
4522 indices [0] = i;
4523 for (j= lbound2; j <= ubound2; j++) {
4524 indices [1] = j;
4525 if (SafeArrayGetElement (safearray, indices, &element) != S_OK)
4526 return 1;
4527 failed = ((element.vt != VT_I4) || (element.lVal != 10*(i+1)+(j+1)));
4528 VariantClear (&element);
4529 if (failed)
4530 return 1;
4534 /* Change the first element of the array to verify that [in] parameters are not marshalled back to the managed side */
4536 indices [0] = 0;
4537 indices [1] = 0;
4538 element.vt = VT_I4;
4539 element.lVal = 333;
4540 SafeArrayPutElement (safearray, indices, &element);
4541 VariantClear (&element);
4543 return 0;
4546 LIBTEST_API int STDCALL
4547 mono_test_marshal_safearray_in_byval_3dim_vt_bstr (SAFEARRAY* safearray)
4549 /* Check that array is one dimensional containing integers mixed with strings from 0 to 12 */
4551 UINT dim;
4552 long lbound1, ubound1, lbound2, ubound2, lbound3, ubound3;
4553 long i, j, k, failed;
4554 long indices [3];
4555 VARIANT element;
4557 VariantInit (&element);
4559 dim = SafeArrayGetDim (safearray);
4560 if (dim != 3)
4561 return 1;
4563 SafeArrayGetLBound (safearray, 1, &lbound1);
4564 SafeArrayGetUBound (safearray, 1, &ubound1);
4566 if ((lbound1 != 0) || (ubound1 != 1))
4567 return 1;
4569 SafeArrayGetLBound (safearray, 2, &lbound2);
4570 SafeArrayGetUBound (safearray, 2, &ubound2);
4572 if ((lbound2 != 0) || (ubound2 != 1))
4573 return 1;
4575 SafeArrayGetLBound (safearray, 3, &lbound3);
4576 SafeArrayGetUBound (safearray, 3, &ubound3);
4578 if ((lbound3 != 0) || (ubound3 != 2))
4579 return 1;
4581 for (i= lbound1; i <= ubound1; i++) {
4582 indices [0] = i;
4583 for (j= lbound2; j <= ubound2; j++) {
4584 indices [1] = j;
4585 for (k= lbound3; k <= ubound3; k++) {
4586 indices [2] = k;
4587 if (SafeArrayGetElement (safearray, indices, &element) != S_OK)
4588 return 1;
4589 failed = ((element.vt != VT_BSTR)
4590 || (VariantChangeType (&element, &element, VARIANT_NOUSEROVERRIDE, VT_I4) != S_OK)
4591 || (element.lVal != 100*(i+1)+10*(j+1)+(k+1)));
4592 VariantClear (&element);
4593 if (failed)
4594 return 1;
4599 /* Change the first element of the array to verify that [in] parameters are not marshalled back to the managed side */
4601 indices [0] = 0;
4602 indices [1] = 0;
4603 indices [2] = 0;
4604 element.vt = VT_BSTR;
4605 element.bstrVal = SysAllocString(L"Should not be copied");
4606 SafeArrayPutElement (safearray, indices, &element);
4607 VariantClear (&element);
4609 return 0;
4612 LIBTEST_API int STDCALL
4613 mono_test_marshal_safearray_in_byref_3dim_vt_bstr (SAFEARRAY** safearray)
4615 return mono_test_marshal_safearray_in_byval_3dim_vt_bstr (*safearray);
4618 LIBTEST_API int STDCALL
4619 mono_test_marshal_safearray_in_out_byref_1dim_empty (SAFEARRAY** safearray)
4621 /* Check that the input array is what is expected and change it so the caller can check */
4622 /* correct marshalling back to managed code */
4624 UINT dim;
4625 long lbound, ubound;
4626 SAFEARRAYBOUND dimensions [1];
4627 long i;
4628 wchar_t buffer [20];
4629 HRESULT hr = S_OK;
4630 long indices [1];
4632 /* Check that in array is one dimensional and empty */
4634 dim = SafeArrayGetDim (*safearray);
4635 if (dim != 1) {
4636 return 1;
4639 SafeArrayGetLBound (*safearray, 1, &lbound);
4640 SafeArrayGetUBound (*safearray, 1, &ubound);
4642 if ((lbound > 0) || (ubound > 0)) {
4643 return 1;
4646 /* Re-dimension the array and return a one-dimensional array of 8 variants filled with "0" to "7" */
4648 dimensions [0].lLbound = 0;
4649 dimensions [0].cElements = 8;
4651 hr = SafeArrayRedim (*safearray, dimensions);
4652 if (hr != S_OK)
4653 return 1;
4655 for (i= dimensions [0].lLbound; i< (dimensions [0].lLbound + dimensions [0].cElements); i++) {
4656 VARIANT vOut;
4657 VariantInit (&vOut);
4658 vOut.vt = VT_BSTR;
4659 _ltow (i,buffer,10);
4660 vOut.bstrVal = SysAllocString (buffer);
4661 indices [0] = i;
4662 if ((hr = SafeArrayPutElement (*safearray, indices, &vOut)) != S_OK) {
4663 VariantClear (&vOut);
4664 SafeArrayDestroy (*safearray);
4665 return hr;
4667 VariantClear (&vOut);
4669 return hr;
4672 LIBTEST_API int STDCALL
4673 mono_test_marshal_safearray_in_out_byref_3dim_vt_bstr (SAFEARRAY** safearray)
4675 /* Check that the input array is what is expected and change it so the caller can check */
4676 /* correct marshalling back to managed code */
4678 UINT dim;
4679 long lbound1, ubound1, lbound2, ubound2, lbound3, ubound3;
4680 SAFEARRAYBOUND dimensions [1];
4681 long i, j, k, failed;
4682 wchar_t buffer [20];
4683 HRESULT hr = S_OK;
4684 long indices [3];
4685 VARIANT element;
4687 VariantInit (&element);
4689 /* Check that in array is three dimensional and contains the expected values */
4691 dim = SafeArrayGetDim (*safearray);
4692 if (dim != 3)
4693 return 1;
4695 SafeArrayGetLBound (*safearray, 1, &lbound1);
4696 SafeArrayGetUBound (*safearray, 1, &ubound1);
4698 if ((lbound1 != 0) || (ubound1 != 1))
4699 return 1;
4701 SafeArrayGetLBound (*safearray, 2, &lbound2);
4702 SafeArrayGetUBound (*safearray, 2, &ubound2);
4704 if ((lbound2 != 0) || (ubound2 != 1))
4705 return 1;
4707 SafeArrayGetLBound (*safearray, 3, &lbound3);
4708 SafeArrayGetUBound (*safearray, 3, &ubound3);
4710 if ((lbound3 != 0) || (ubound3 != 2))
4711 return 1;
4713 for (i= lbound1; i <= ubound1; i++) {
4714 indices [0] = i;
4715 for (j= lbound2; j <= ubound2; j++) {
4716 indices [1] = j;
4717 for (k= lbound3; k <= ubound3; k++) {
4718 indices [2] = k;
4719 if (SafeArrayGetElement (*safearray, indices, &element) != S_OK)
4720 return 1;
4721 failed = ((element.vt != VT_BSTR)
4722 || (VariantChangeType (&element, &element, VARIANT_NOUSEROVERRIDE, VT_I4) != S_OK)
4723 || (element.lVal != 100*(i+1)+10*(j+1)+(k+1)));
4724 VariantClear (&element);
4725 if (failed)
4726 return 1;
4731 hr = SafeArrayDestroy (*safearray);
4732 if (hr != S_OK)
4733 return 1;
4735 /* Return a new one-dimensional array of 8 variants filled with "0" to "7" */
4737 dimensions [0].lLbound = 0;
4738 dimensions [0].cElements = 8;
4740 *safearray = SafeArrayCreate (VT_VARIANT, 1, dimensions);
4742 for (i= dimensions [0].lLbound; i< (dimensions [0].lLbound + dimensions [0].cElements); i++) {
4743 VARIANT vOut;
4744 VariantInit (&vOut);
4745 vOut.vt = VT_BSTR;
4746 _ltow (i,buffer,10);
4747 vOut.bstrVal = SysAllocString (buffer);
4748 indices [0] = i;
4749 if ((hr = SafeArrayPutElement (*safearray, indices, &vOut)) != S_OK) {
4750 VariantClear (&vOut);
4751 SafeArrayDestroy (*safearray);
4752 return hr;
4754 VariantClear (&vOut);
4756 return hr;
4759 LIBTEST_API int STDCALL
4760 mono_test_marshal_safearray_in_out_byref_1dim_vt_i4 (SAFEARRAY** safearray)
4762 /* Check that the input array is what is expected and change it so the caller can check */
4763 /* correct marshalling back to managed code */
4765 UINT dim;
4766 long lbound1, ubound1;
4767 long i, failed;
4768 HRESULT hr = S_OK;
4769 long indices [1];
4770 VARIANT element;
4772 VariantInit (&element);
4774 /* Check that in array is one dimensional and contains the expected value */
4776 dim = SafeArrayGetDim (*safearray);
4777 if (dim != 1)
4778 return 1;
4780 SafeArrayGetLBound (*safearray, 1, &lbound1);
4781 SafeArrayGetUBound (*safearray, 1, &ubound1);
4783 ubound1 = 1;
4784 if ((lbound1 != 0) || (ubound1 != 1))
4785 return 1;
4786 ubound1 = 0;
4788 for (i= lbound1; i <= ubound1; i++) {
4789 indices [0] = i;
4790 if (SafeArrayGetElement (*safearray, indices, &element) != S_OK)
4791 return 1;
4792 failed = (element.vt != VT_I4) || (element.lVal != i+1);
4793 VariantClear (&element);
4794 if (failed)
4795 return 1;
4798 /* Change one of the elements of the array to verify that [out] parameter is marshalled back to the managed side */
4800 indices [0] = 0;
4801 element.vt = VT_I4;
4802 element.lVal = -1;
4803 SafeArrayPutElement (*safearray, indices, &element);
4804 VariantClear (&element);
4806 return hr;
4809 LIBTEST_API int STDCALL
4810 mono_test_marshal_safearray_in_out_byval_1dim_vt_i4 (SAFEARRAY* safearray)
4812 /* Check that the input array is what is expected and change it so the caller can check */
4813 /* correct marshalling back to managed code */
4815 UINT dim;
4816 long lbound1, ubound1;
4817 SAFEARRAYBOUND dimensions [1];
4818 long i, failed;
4819 HRESULT hr = S_OK;
4820 long indices [1];
4821 VARIANT element;
4823 VariantInit (&element);
4825 /* Check that in array is one dimensional and contains the expected value */
4827 dim = SafeArrayGetDim (safearray);
4828 if (dim != 1)
4829 return 1;
4831 SafeArrayGetLBound (safearray, 1, &lbound1);
4832 SafeArrayGetUBound (safearray, 1, &ubound1);
4834 if ((lbound1 != 0) || (ubound1 != 0))
4835 return 1;
4837 for (i= lbound1; i <= ubound1; i++) {
4838 indices [0] = i;
4839 if (SafeArrayGetElement (safearray, indices, &element) != S_OK)
4840 return 1;
4841 failed = (element.vt != VT_I4) || (element.lVal != i+1);
4842 VariantClear (&element);
4843 if (failed)
4844 return 1;
4847 /* Change the array to verify how [out] parameter is marshalled back to the managed side */
4849 /* Redimension the array */
4850 dimensions [0].lLbound = lbound1;
4851 dimensions [0].cElements = 2;
4852 hr = SafeArrayRedim(safearray, dimensions);
4854 indices [0] = 0;
4855 element.vt = VT_I4;
4856 element.lVal = 12345;
4857 SafeArrayPutElement (safearray, indices, &element);
4858 VariantClear (&element);
4860 indices [0] = 1;
4861 element.vt = VT_I4;
4862 element.lVal = -12345;
4863 SafeArrayPutElement (safearray, indices, &element);
4864 VariantClear (&element);
4866 return hr;
4869 LIBTEST_API int STDCALL
4870 mono_test_marshal_safearray_in_out_byval_3dim_vt_bstr (SAFEARRAY* safearray)
4872 /* Check that the input array is what is expected and change it so the caller can check */
4873 /* correct marshalling back to managed code */
4875 UINT dim;
4876 long lbound1, ubound1, lbound2, ubound2, lbound3, ubound3;
4877 long i, j, k, failed;
4878 HRESULT hr = S_OK;
4879 long indices [3];
4880 VARIANT element;
4882 VariantInit (&element);
4884 /* Check that in array is three dimensional and contains the expected values */
4886 dim = SafeArrayGetDim (safearray);
4887 if (dim != 3)
4888 return 1;
4890 SafeArrayGetLBound (safearray, 1, &lbound1);
4891 SafeArrayGetUBound (safearray, 1, &ubound1);
4893 if ((lbound1 != 0) || (ubound1 != 1))
4894 return 1;
4896 SafeArrayGetLBound (safearray, 2, &lbound2);
4897 SafeArrayGetUBound (safearray, 2, &ubound2);
4899 if ((lbound2 != 0) || (ubound2 != 1))
4900 return 1;
4902 SafeArrayGetLBound (safearray, 3, &lbound3);
4903 SafeArrayGetUBound (safearray, 3, &ubound3);
4905 if ((lbound3 != 0) || (ubound3 != 2))
4906 return 1;
4908 for (i= lbound1; i <= ubound1; i++) {
4909 indices [0] = i;
4910 for (j= lbound2; j <= ubound2; j++) {
4911 indices [1] = j;
4912 for (k= lbound3; k <= ubound3; k++) {
4913 indices [2] = k;
4914 if (SafeArrayGetElement (safearray, indices, &element) != S_OK)
4915 return 1;
4916 failed = ((element.vt != VT_BSTR)
4917 || (VariantChangeType (&element, &element, VARIANT_NOUSEROVERRIDE, VT_I4) != S_OK)
4918 || (element.lVal != 100*(i+1)+10*(j+1)+(k+1)));
4919 VariantClear (&element);
4920 if (failed)
4921 return 1;
4926 /* Change the elements of the array to verify that [out] parameter is marshalled back to the managed side */
4928 indices [0] = 1;
4929 indices [1] = 1;
4930 indices [2] = 2;
4931 element.vt = VT_I4;
4932 element.lVal = 333;
4933 SafeArrayPutElement (safearray, indices, &element);
4934 VariantClear (&element);
4936 indices [0] = 1;
4937 indices [1] = 1;
4938 indices [2] = 1;
4939 element.vt = VT_I4;
4940 element.lVal = 111;
4941 SafeArrayPutElement (safearray, indices, &element);
4942 VariantClear (&element);
4944 indices [0] = 0;
4945 indices [1] = 1;
4946 indices [2] = 0;
4947 element.vt = VT_BSTR;
4948 element.bstrVal = marshal_bstr_alloc("ABCDEFG");
4949 SafeArrayPutElement (safearray, indices, &element);
4950 VariantClear (&element);
4952 return hr;
4955 LIBTEST_API int STDCALL
4956 mono_test_marshal_safearray_mixed(
4957 SAFEARRAY *safearray1,
4958 SAFEARRAY **safearray2,
4959 SAFEARRAY *safearray3,
4960 SAFEARRAY **safearray4
4963 HRESULT hr = S_OK;
4965 /* Initialize out parameters */
4966 *safearray2 = NULL;
4968 /* array1: Check that in array is one dimensional and contains the expected value */
4969 hr = mono_test_marshal_safearray_in_out_byval_1dim_vt_i4 (safearray1);
4971 /* array2: Fill in with some values to check on the managed side */
4972 if (hr == S_OK)
4973 hr = mono_test_marshal_safearray_out_1dim_vt_bstr (safearray2);
4975 /* array3: Check that in array is one dimensional and contains the expected value */
4976 if (hr == S_OK)
4977 hr = mono_test_marshal_safearray_in_byval_1dim_vt_mixed(safearray3);
4979 /* array4: Check input values and fill in with some values to check on the managed side */
4980 if (hr == S_OK)
4981 hr = mono_test_marshal_safearray_in_out_byref_3dim_vt_bstr(safearray4);
4983 return hr;
4986 #endif