#include <errno.h>
#include <time.h>
+#ifdef WIN32
+#include <windows.h>
+#include "initguid.h"
+#endif
+
#ifdef WIN32
#define STDCALL __stdcall
#else
return sum;
}
+STDCALL int
+mono_test_marshal_out_array (int *a1)
+{
+ int i;
+
+ for (i = 0; i < 50; i++) {
+ a1 [i] = i;
+ }
+
+ return 0;
+}
+
STDCALL int
mono_test_marshal_inout_nonblittable_array (gunichar2 *a1)
{
gunichar2 *d2;
} simplestruct;
+typedef struct {
+ double x;
+ double y;
+} point;
+
STDCALL simplestruct
mono_test_return_vtype (int i)
{
ss->b = 0;
ss->c = 1;
ss->d = "TEST2";
-
+
return func (a, ss, b);
}
SimpleDelegate func, func2;
} DelegateStruct;
-STDCALL int
+STDCALL DelegateStruct
mono_test_marshal_delegate_struct (DelegateStruct ds)
{
- return ds.func (ds.a) + ds.func2 (ds.a);
+ DelegateStruct res;
+
+ res.a = ds.func (ds.a) + ds.func2 (ds.a);
+ res.func = ds.func;
+ res.func2 = ds.func2;
+
+ return res;
}
STDCALL int
return 1;
}
+STDCALL int
+mono_test_marshal_byref_struct (simplestruct *ss, int a, int b, int c, char *d)
+{
+ gboolean res = (ss->a == a && ss->b == b && ss->c == c && strcmp (ss->d, d) == 0);
+
+ marshal_free (ss->d);
+
+ ss->a = !ss->a;
+ ss->b = !ss->b;
+ ss->c = !ss->c;
+ ss->d = g_strdup ("DEF");
+
+ return res ? 0 : 1;
+}
+
typedef struct {
int a;
int b;
return 1;
}
+STDCALL int
+mono_test_marshal_lpstruct (simplestruct *ss)
+{
+ if (ss->a == 0 && ss->b == 1 && ss->c == 0 &&
+ !strcmp (ss->d, "TEST"))
+ return 0;
+
+ return 1;
+}
+
+STDCALL int
+mono_test_marshal_lpstruct_blittable (point *p)
+{
+ if (p->x == 1.0 && p->y == 2.0)
+ return 0;
+ else
+ return 1;
+}
+
STDCALL int
mono_test_marshal_struct_array (simplestruct2 *ss)
{
int i;
void *p;
+ /* Yes, this is correct, we are only trying to determine the value of the stack here */
p = &i;
return p;
}
return 0;
}
+typedef int (STDCALL *InOutByvalClassDelegate) (simplestruct *ss);
+
+STDCALL int
+mono_test_marshal_inout_byval_class_delegate (InOutByvalClassDelegate delegate)
+{
+ int res;
+ simplestruct ss;
+
+ ss.a = FALSE;
+ ss.b = TRUE;
+ ss.c = FALSE;
+ ss.d = g_strdup_printf ("%s", "FOO");
+
+ res = delegate (&ss);
+ if (res != 0)
+ return 1;
+
+ if (!(ss.a && !ss.b && ss.c && !strcmp (ss.d, "RES")))
+ return 2;
+
+ return 0;
+}
+
typedef int (STDCALL *SimpleDelegate8) (gunichar2 *s);
STDCALL int
if (strcmp (s, "ABCD") != 0)
return 1;
strncpy(s, m, n);
+ s [n] = '\0';
+ return 0;
+}
+
+STDCALL int
+mono_test_marshal_stringbuilder_default (char *s, int n)
+{
+ const char m[] = "This is my message. Isn't it nice?";
+
+ strncpy(s, m, n);
+ s [n] = '\0';
return 0;
}
s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
len = (len * 2) + 2;
- if (len > n)
- len = n;
+ if (len > (n * 2))
+ len = n * 2;
memcpy (s, s2, len);
g_free (s2);
{
// printf ("mono_test_empty_struct %d %d\n", a, b);
+ // Intel icc on ia64 passes 'es' in 2 registers
+#if defined(__ia64) && defined(__INTEL_COMPILER)
+ return 0;
+#else
if (a == 1 && b == 2)
return 0;
return 1;
+#endif
}
typedef struct {
return (ret != 0);
}
+typedef struct {
+ guint16 a[4];
+ int flag;
+} ByValStrStruct_Unicode;
+
+STDCALL int
+mono_test_byvalstr_check_unicode (ByValStrStruct_Unicode *ref, int test)
+{
+ if (ref->flag != 0x1234abcd){
+ printf ("overwritten data");
+ return 1;
+ }
+
+ if (test == 1 || test == 3){
+ if (ref->a [0] != '1' ||
+ ref->a [1] != '2' ||
+ ref->a [2] != '3')
+ return 1;
+ return 0;
+ }
+ if (test == 2){
+ if (ref->a [0] != '1' ||
+ ref->a [1] != '2')
+ return 1;
+ return 0;
+ }
+ return 10;
+}
+
STDCALL int
NameManglingAnsi (char *data)
{
typedef struct {
int a;
int b;
-} VectorList;
+} BlittableClass;
-STDCALL VectorList*
-TestVectorList (VectorList *vl)
+STDCALL BlittableClass*
+TestBlittableClass (BlittableClass *vl)
{
- VectorList *res;
+ BlittableClass *res;
- // printf ("TestVectorList %d %d\n", vl->a, vl->b);
+ // printf ("TestBlittableClass %d %d\n", vl->a, vl->b);
- vl->a++;
- vl->b++;
+ if (vl) {
+ vl->a++;
+ vl->b++;
- res = g_new0 (VectorList, 1);
- memcpy (res, vl, sizeof (VectorList));
+ res = g_new0 (BlittableClass, 1);
+ memcpy (res, vl, sizeof (BlittableClass));
+ } else {
+ res = g_new0 (BlittableClass, 1);
+ res->a = 42;
+ res->b = 43;
+ }
return res;
}
-typedef struct _OSVERSIONINFO
+typedef struct OSVERSIONINFO_STRUCT
{
int a;
int b;
-} OSVERSIONINFO;
+} OSVERSIONINFO_STRUCT;
STDCALL int
-GetVersionEx (OSVERSIONINFO *osvi)
+MyGetVersionEx (OSVERSIONINFO_STRUCT *osvi)
{
// printf ("GOT %d %d\n", osvi->a, osvi->b);
}
STDCALL int
-BugGetVersionEx (int a, int b, int c, int d, int e, int f, int g, int h, OSVERSIONINFO *osvi)
+BugGetVersionEx (int a, int b, int c, int d, int e, int f, int g, int h, OSVERSIONINFO_STRUCT *osvi)
{
// printf ("GOT %d %d\n", osvi->a, osvi->b);
return osvi->a + osvi->b;
}
-typedef struct {
- double x;
- double y;
-} point;
-
STDCALL int
mono_test_marshal_point (point pt)
{
return res;
}
-#ifdef WIN32
-extern __declspec(dllimport) __stdcall void SetLastError(int x);
-#endif
-
STDCALL void
mono_test_last_error (int err)
{
return 1;
}
+typedef struct
+{
+ int i;
+ int j;
+ int k;
+ char *s;
+} AsAnyStruct;
+
+STDCALL int
+mono_test_marshal_asany_in (void* ptr)
+{
+ AsAnyStruct* asAny = ptr;
+ int res = asAny->i + asAny->j + asAny->k;
+
+ return res;
+}
+
+STDCALL int
+mono_test_marshal_asany_inout (void* ptr)
+{
+ AsAnyStruct* asAny = ptr;
+ int res = asAny->i + asAny->j + asAny->k;
+
+ marshal_free (asAny->s);
+
+ asAny->i = 10;
+ asAny->j = 20;
+ asAny->k = 30;
+ asAny->s = 0;
+
+ return res;
+}
+
+STDCALL int
+mono_test_marshal_asany_out (void* ptr)
+{
+ AsAnyStruct* asAny = ptr;
+ int res = asAny->i + asAny->j + asAny->k;
+
+ asAny->i = 10;
+ asAny->j = 20;
+ asAny->k = 30;
+ asAny->s = 0;
+
+ return res;
+}
+
/*
* AMD64 marshalling tests.
*/
return s;
}
+/*
+ * IA64 marshalling tests.
+ */
+typedef struct test_struct5 {
+ float d1, d2;
+} test_struct5;
+
+STDCALL test_struct5
+mono_test_marshal_ia64_pass_return_struct5 (double d1, double d2, test_struct5 s, double d3, double d4)
+{
+ s.d1 += d1 + d2;
+ s.d2 += d3 + d4;
+
+ return s;
+}
+
+typedef struct test_struct6 {
+ double d1, d2;
+} test_struct6;
+
+STDCALL test_struct6
+mono_test_marshal_ia64_pass_return_struct6 (double d1, double d2, test_struct6 s, double d3, double d4)
+{
+ s.d1 += d1 + d2;
+ s.d2 += d3 + d4;
+
+ return s;
+}
+
static guint32 custom_res [2];
STDCALL void*
return &custom_res;
}
+STDCALL int
+mono_test_marshal_pass_out_custom (int i, guint32 **ptr, int j)
+{
+ custom_res [0] = 0;
+ custom_res [1] = i + j + 10;
+
+ *ptr = custom_res;
+
+ return 0;
+}
+
+STDCALL int
+mono_test_marshal_pass_inout_custom (int i, guint32 *ptr, int j)
+{
+ ptr [0] = 0;
+ ptr [1] = i + ptr [1] + j;
+
+ return 0;
+}
+
+STDCALL int
+mono_test_marshal_pass_out_byval_custom (int i, guint32 *ptr, int j)
+{
+ return ptr == NULL ? 0 : 1;
+}
+
+STDCALL int
+mono_test_marshal_pass_byref_custom (int i, guint32 **ptr, int j)
+{
+ (*ptr)[1] += i + j;
+
+ return 0;
+}
+
+STDCALL void*
+mono_test_marshal_pass_return_custom2 (int i, guint32 *ptr, int j)
+{
+ g_assert_not_reached ();
+
+ return NULL;
+}
+
+STDCALL void*
+mono_test_marshal_pass_return_custom_null (int i, guint32 *ptr, int j)
+{
+ g_assert (ptr == NULL);
+
+ return NULL;
+}
+
typedef void *(STDCALL *PassReturnPtrDelegate) (void *ptr);
STDCALL int
return res;
}
+STDCALL int
+mono_test_marshal_pass_return_custom_null_in_delegate (PassReturnPtrDelegate del)
+{
+ void *ptr = del (NULL);
+
+ return (ptr == NULL) ? 15 : 0;
+}
+
+typedef void (STDCALL *CustomOutParamDelegate) (void **pptr);
+
+STDCALL int
+mono_test_marshal_custom_out_param_delegate (CustomOutParamDelegate del)
+{
+ void* pptr = del;
+
+ del (&pptr);
+
+ if(pptr != NULL)
+ return 1;
+
+ return 0;
+}
+
typedef int (STDCALL *ReturnEnumDelegate) (int e);
STDCALL int
return del (len, NULL, arr);
}
+STDCALL int
+mono_test_marshal_out_array_delegate (int *arr, int len, ArrayDelegate del)
+{
+ del (len, NULL, arr);
+
+ if ((arr [0] != 1) || (arr [1] != 2))
+ return 1;
+ else
+ return 0;
+}
+
+typedef gunichar2* (STDCALL *UnicodeStringDelegate) (gunichar2 *message);
+
+STDCALL int
+mono_test_marshal_return_unicode_string_delegate (UnicodeStringDelegate del)
+{
+ const char m[] = "abcdef";
+ gunichar2 *s2, *res;
+ glong len;
+
+ s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
+
+ res = del (s2);
+
+ marshal_free (res);
+
+ return 0;
+}
+
+STDCALL int
+mono_test_marshal_out_string_array_delegate (char **arr, int len, ArrayDelegate del)
+{
+ del (len, NULL, arr);
+
+ if (!strcmp (arr [0], "ABC") && !strcmp (arr [1], "DEF"))
+ return 0;
+ else
+ return 1;
+}
+
+typedef int (*CdeclDelegate) (int i, int j);
+
+STDCALL int
+mono_test_marshal_cdecl_delegate (CdeclDelegate del)
+{
+ int i;
+
+ for (i = 0; i < 1000; ++i)
+ del (1, 2);
+
+ return 0;
+}
+
+typedef char** (*ReturnStringArrayDelegate) (int i);
+
+STDCALL int
+mono_test_marshal_return_string_array_delegate (ReturnStringArrayDelegate d)
+{
+ char **arr = d (2);
+ int res;
+
+ if (arr == NULL)
+ return 3;
+
+ if (strcmp (arr [0], "ABC") || strcmp (arr [1], "DEF"))
+ res = 1;
+ else
+ res = 0;
+
+ marshal_free (arr);
+
+ return res;
+}
+
+STDCALL int
+add_delegate (int i, int j)
+{
+ return i + j;
+}
+
+STDCALL gpointer
+mono_test_marshal_return_fnptr (void)
+{
+ return &add_delegate;
+}
+
+STDCALL int
+mono_xr (int code)
+{
+ printf ("codigo %x\n", code);
+ return code + 1234;
+}
+
+typedef struct {
+ int handle;
+} HandleRef;
+
+STDCALL HandleRef
+mono_xr_as_handle (int code)
+{
+ HandleRef ref;
+
+ return ref;
+}
+
+typedef struct {
+ int a;
+ void *handle1;
+ void *handle2;
+ int b;
+} HandleStructs;
+
+STDCALL int
+mono_safe_handle_struct_ref (HandleStructs *x)
+{
+ printf ("Dingus Ref! \n");
+ printf ("Values: %d %d %d %d\n", x->a, x->b, x->handle1, x->handle2);
+ if (x->a != 1234)
+ return 1;
+ if (x->b != 8743)
+ return 2;
+
+ if (x->handle1 != (void*) 0x7080feed)
+ return 3;
+
+ if (x->handle2 != (void*) 0x1234abcd)
+ return 4;
+
+ return 0xf00d;
+}
+
+STDCALL int
+mono_safe_handle_struct (HandleStructs x)
+{
+ printf ("Dingus Standard! \n");
+ printf ("Values: %d %d %d %d\n", x.a, x.b, x.handle1, x.handle2);
+ if (x.a != 1234)
+ return 1;
+ if (x.b != 8743)
+ return 2;
+
+ if (x.handle1 != (void*) 0x7080feed)
+ return 3;
+
+ if (x.handle2 != (void*) 0x1234abcd)
+ return 4;
+
+ return 0xf00f;
+}
+
+typedef struct {
+ void *a;
+} TrivialHandle;
+
+STDCALL int
+mono_safe_handle_struct_simple (TrivialHandle x)
+{
+ printf ("The value is %d\n", x.a);
+ return ((int)x.a) * 2;
+}
+
+STDCALL int
+mono_safe_handle_return ()
+{
+ return 0x1000f00d;
+}
+
+STDCALL void
+mono_safe_handle_ref (void **handle)
+{
+ if (*handle != 0){
+ *handle = (void *) 0xbad;
+ return;
+ }
+
+ *handle = (void *) 0x800d;
+}
+/*
+ * COM INTEROP TESTS
+ */
+
+#ifdef WIN32
+
+STDCALL int
+mono_test_marshal_bstr_in(BSTR bstr)
+{
+ if (!wcscmp(bstr, L"mono_test_marshal_bstr_in"))
+ return 0;
+ return 1;
+}
+
+STDCALL int
+mono_test_marshal_bstr_out(BSTR* bstr)
+{
+ *bstr = SysAllocString(L"mono_test_marshal_bstr_out");
+ return 0;
+}
+
+STDCALL int
+mono_test_marshal_bstr_in_null(BSTR bstr)
+{
+ if (!bstr)
+ return 0;
+ return 1;
+}
+
+STDCALL int
+mono_test_marshal_bstr_out_null(BSTR* bstr)
+{
+ *bstr = NULL;
+ return 0;
+}
+
+STDCALL int
+mono_test_marshal_variant_in_sbyte(VARIANT variant)
+{
+ if (variant.vt == VT_I1 && variant.cVal == 100)
+ return 0;
+ return 1;
+}
+
+STDCALL int
+mono_test_marshal_variant_in_byte(VARIANT variant)
+{
+ if (variant.vt == VT_UI1 && variant.bVal == 100)
+ return 0;
+ return 1;
+}
+
+STDCALL int
+mono_test_marshal_variant_in_short(VARIANT variant)
+{
+ if (variant.vt == VT_I2 && variant.iVal == 314)
+ return 0;
+ return 1;
+}
+
+STDCALL int
+mono_test_marshal_variant_in_ushort(VARIANT variant)
+{
+ if (variant.vt == VT_UI2 && variant.uiVal == 314)
+ return 0;
+ return 1;
+}
+
+STDCALL int
+mono_test_marshal_variant_in_int(VARIANT variant)
+{
+ if (variant.vt == VT_I4 && variant.lVal == 314)
+ return 0;
+ return 1;
+}
+
+STDCALL int
+mono_test_marshal_variant_in_uint(VARIANT variant)
+{
+ if (variant.vt == VT_UI4 && variant.ulVal == 314)
+ return 0;
+ return 1;
+}
+
+STDCALL int
+mono_test_marshal_variant_in_long(VARIANT variant)
+{
+ if (variant.vt == VT_I8 && variant.llVal == 314)
+ return 0;
+ return 1;
+}
+
+STDCALL int
+mono_test_marshal_variant_in_ulong(VARIANT variant)
+{
+ if (variant.vt == VT_UI8 && variant.ullVal == 314)
+ return 0;
+ return 1;
+}
+
+STDCALL int
+mono_test_marshal_variant_in_float(VARIANT variant)
+{
+ if (variant.vt == VT_R4 && (variant.fltVal - 3.14)/3.14 < .001)
+ return 0;
+ return 1;
+}
+
+STDCALL int
+mono_test_marshal_variant_in_double(VARIANT variant)
+{
+ if (variant.vt == VT_R8 && (variant.dblVal - 3.14)/3.14 < .001)
+ return 0;
+ return 1;
+}
+
+STDCALL int
+mono_test_marshal_variant_in_bstr(VARIANT variant)
+{
+ if (variant.vt == VT_BSTR && !wcscmp(variant.bstrVal, L"PI"))
+ return 0;
+ return 1;
+}
+
+STDCALL int
+mono_test_marshal_variant_in_bool_true (VARIANT variant)
+{
+ if (variant.vt == VT_BOOL && variant.boolVal == VARIANT_TRUE)
+ return 0;
+ return 1;
+}
+
+STDCALL int
+mono_test_marshal_variant_in_bool_false (VARIANT variant)
+{
+ if (variant.vt == VT_BOOL && variant.boolVal == VARIANT_FALSE)
+ return 0;
+ return 1;
+}
+
+STDCALL int
+mono_test_marshal_variant_out_sbyte(VARIANT* variant)
+{
+ variant->vt = VT_I1;
+ variant->cVal = 100;
+
+ return 0;
+}
+
+STDCALL int
+mono_test_marshal_variant_out_byte(VARIANT* variant)
+{
+ variant->vt = VT_UI1;
+ variant->bVal = 100;
+
+ return 0;
+}
+
+STDCALL int
+mono_test_marshal_variant_out_short(VARIANT* variant)
+{
+ variant->vt = VT_I2;
+ variant->iVal = 314;
+
+ return 0;
+}
+
+STDCALL int
+mono_test_marshal_variant_out_ushort(VARIANT* variant)
+{
+ variant->vt = VT_UI2;
+ variant->uiVal = 314;
+
+ return 0;
+}
+
+STDCALL int
+mono_test_marshal_variant_out_int(VARIANT* variant)
+{
+ variant->vt = VT_I4;
+ variant->lVal = 314;
+
+ return 0;
+}
+
+STDCALL int
+mono_test_marshal_variant_out_uint(VARIANT* variant)
+{
+ variant->vt = VT_UI4;
+ variant->ulVal = 314;
+
+ return 0;
+}
+
+STDCALL int
+mono_test_marshal_variant_out_long(VARIANT* variant)
+{
+ variant->vt = VT_I8;
+ variant->llVal = 314;
+
+ return 0;
+}
+
+STDCALL int
+mono_test_marshal_variant_out_ulong(VARIANT* variant)
+{
+ variant->vt = VT_UI8;
+ variant->ullVal = 314;
+
+ return 0;
+}
+
+STDCALL int
+mono_test_marshal_variant_out_float(VARIANT* variant)
+{
+ variant->vt = VT_R4;
+ variant->fltVal = 3.14;
+
+ return 0;
+}
+
+STDCALL int
+mono_test_marshal_variant_out_double(VARIANT* variant)
+{
+ variant->vt = VT_R8;
+ variant->dblVal = 3.14;
+
+ return 0;
+}
+
+STDCALL int
+mono_test_marshal_variant_out_bstr(VARIANT* variant)
+{
+ variant->vt = VT_BSTR;
+ variant->bstrVal = SysAllocString(L"PI");
+
+ return 0;
+}
+
+STDCALL int
+mono_test_marshal_variant_out_bool_true (VARIANT* variant)
+{
+ variant->vt = VT_BOOL;
+ variant->boolVal = VARIANT_TRUE;
+
+ return 0;
+}
+
+STDCALL int
+mono_test_marshal_variant_out_bool_false (VARIANT* variant)
+{
+ variant->vt = VT_BOOL;
+ variant->boolVal = VARIANT_FALSE;
+
+ return 0;
+}
+
+typedef int (STDCALL *VarFunc) (int vt, VARIANT variant);
+typedef int (STDCALL *VarRefFunc) (int vt, VARIANT* variant);
+
+STDCALL int
+mono_test_marshal_variant_in_sbyte_unmanaged(VarFunc func)
+{
+ VARIANT vt;
+ vt.vt = VT_I1;
+ vt.cVal = -100;
+ return func (VT_I1, vt);
+}
+
+STDCALL int
+mono_test_marshal_variant_in_byte_unmanaged(VarFunc func)
+{
+ VARIANT vt;
+ vt.vt = VT_UI1;
+ vt.bVal = 100;
+ return func (VT_UI1, vt);
+}
+
+STDCALL int
+mono_test_marshal_variant_in_short_unmanaged(VarFunc func)
+{
+ VARIANT vt;
+ vt.vt = VT_I2;
+ vt.iVal = -100;
+ return func (VT_I2, vt);
+}
+
+STDCALL int
+mono_test_marshal_variant_in_ushort_unmanaged(VarFunc func)
+{
+ VARIANT vt;
+ vt.vt = VT_UI2;
+ vt.uiVal = 100;
+ return func (VT_UI2, vt);
+}
+
+STDCALL int
+mono_test_marshal_variant_in_int_unmanaged(VarFunc func)
+{
+ VARIANT vt;
+ vt.vt = VT_I4;
+ vt.lVal = -100;
+ return func (VT_I4, vt);
+}
+
+STDCALL int
+mono_test_marshal_variant_in_uint_unmanaged(VarFunc func)
+{
+ VARIANT vt;
+ vt.vt = VT_UI4;
+ vt.ulVal = 100;
+ return func (VT_UI4, vt);
+}
+
+STDCALL int
+mono_test_marshal_variant_in_long_unmanaged(VarFunc func)
+{
+ VARIANT vt;
+ vt.vt = VT_I8;
+ vt.llVal = -100;
+ return func (VT_I8, vt);
+}
+
+STDCALL int
+mono_test_marshal_variant_in_ulong_unmanaged(VarFunc func)
+{
+ VARIANT vt;
+ vt.vt = VT_UI8;
+ vt.ullVal = 100;
+ return func (VT_UI8, vt);
+}
+
+STDCALL int
+mono_test_marshal_variant_in_float_unmanaged(VarFunc func)
+{
+ VARIANT vt;
+ vt.vt = VT_R4;
+ vt.fltVal = 3.14;
+ return func (VT_R4, vt);
+}
+
+STDCALL int
+mono_test_marshal_variant_in_double_unmanaged(VarFunc func)
+{
+ VARIANT vt;
+ vt.vt = VT_R8;
+ vt.dblVal = 3.14;
+ return func (VT_R8, vt);
+}
+
+STDCALL int
+mono_test_marshal_variant_in_bstr_unmanaged(VarFunc func)
+{
+ VARIANT vt;
+ vt.vt = VT_BSTR;
+ vt.bstrVal = SysAllocString(L"PI");
+ return func (VT_BSTR, vt);
+}
+
+STDCALL int
+mono_test_marshal_variant_in_bool_true_unmanaged(VarFunc func)
+{
+ VARIANT vt;
+ vt.vt = VT_BOOL;
+ vt.boolVal = VARIANT_TRUE;
+ return func (VT_BOOL, vt);
+}
+
+STDCALL int
+mono_test_marshal_variant_in_bool_false_unmanaged(VarFunc func)
+{
+ VARIANT vt;
+ vt.vt = VT_BOOL;
+ vt.boolVal = VARIANT_FALSE;
+ return func (VT_BOOL, vt);
+}
+
+STDCALL int
+mono_test_marshal_variant_out_sbyte_unmanaged(VarRefFunc func)
+{
+ VARIANT vt;
+ VariantInit (&vt);
+ func (VT_I1, &vt);
+ if (vt.vt == VT_I1 && vt.cVal == -100)
+ return 0;
+ return 1;
+}
+
+STDCALL int
+mono_test_marshal_variant_out_byte_unmanaged(VarRefFunc func)
+{
+ VARIANT vt;
+ VariantInit (&vt);
+ func (VT_UI1, &vt);
+ if (vt.vt == VT_UI1 && vt.bVal == 100)
+ return 0;
+ return 1;
+}
+
+STDCALL int
+mono_test_marshal_variant_out_short_unmanaged(VarRefFunc func)
+{
+ VARIANT vt;
+ VariantInit (&vt);
+ func (VT_I2, &vt);
+ if (vt.vt == VT_I2 && vt.iVal == -100)
+ return 0;
+ return 1;
+}
+
+STDCALL int
+mono_test_marshal_variant_out_ushort_unmanaged(VarRefFunc func)
+{
+ VARIANT vt;
+ VariantInit (&vt);
+ func (VT_UI2, &vt);
+ if (vt.vt == VT_UI2 && vt.uiVal == 100)
+ return 0;
+ return 1;
+}
+
+STDCALL int
+mono_test_marshal_variant_out_int_unmanaged(VarRefFunc func)
+{
+ VARIANT vt;
+ VariantInit (&vt);
+ func (VT_I4, &vt);
+ if (vt.vt == VT_I4 && vt.lVal == -100)
+ return 0;
+ return 1;
+}
+
+STDCALL int
+mono_test_marshal_variant_out_uint_unmanaged(VarRefFunc func)
+{
+ VARIANT vt;
+ VariantInit (&vt);
+ func (VT_UI4, &vt);
+ if (vt.vt == VT_UI4 && vt.ulVal == 100)
+ return 0;
+ return 1;
+}
+
+STDCALL int
+mono_test_marshal_variant_out_long_unmanaged(VarRefFunc func)
+{
+ VARIANT vt;
+ VariantInit (&vt);
+ func (VT_I8, &vt);
+ if (vt.vt == VT_I8 && vt.llVal == -100)
+ return 0;
+ return 1;
+}
+
+STDCALL int
+mono_test_marshal_variant_out_ulong_unmanaged(VarRefFunc func)
+{
+ VARIANT vt;
+ VariantInit (&vt);
+ func (VT_UI8, &vt);
+ if (vt.vt == VT_UI8 && vt.ullVal == 100)
+ return 0;
+ return 1;
+}
+
+STDCALL int
+mono_test_marshal_variant_out_float_unmanaged(VarRefFunc func)
+{
+ VARIANT vt;
+ VariantInit (&vt);
+ func (VT_R4, &vt);
+ if (vt.vt == VT_R4 && fabs (vt.fltVal - 3.14f) < 1e-10)
+ return 0;
+ return 1;
+}
+
+STDCALL int
+mono_test_marshal_variant_out_double_unmanaged(VarRefFunc func)
+{
+ VARIANT vt;
+ VariantInit (&vt);
+ func (VT_R8, &vt);
+ if (vt.vt == VT_R8 && fabs (vt.dblVal - 3.14) < 1e-10)
+ return 0;
+ return 1;
+}
+
+STDCALL int
+mono_test_marshal_variant_out_bstr_unmanaged(VarRefFunc func)
+{
+ VARIANT vt;
+ VariantInit (&vt);
+ func (VT_BSTR, &vt);
+ if (vt.vt == VT_BSTR && !wcscmp(vt.bstrVal, L"PI"))
+ return 0;
+ return 1;
+}
+
+STDCALL int
+mono_test_marshal_variant_out_bool_true_unmanaged(VarRefFunc func)
+{
+ VARIANT vt;
+ VariantInit (&vt);
+ func (VT_BOOL, &vt);
+ if (vt.vt == VT_BOOL && vt.boolVal == VARIANT_TRUE)
+ return 0;
+ return 1;
+}
+
+STDCALL int
+mono_test_marshal_variant_out_bool_false_unmanaged(VarRefFunc func)
+{
+ VARIANT vt;
+ VariantInit (&vt);
+ func (VT_BOOL, &vt);
+ if (vt.vt == VT_BOOL && vt.boolVal == VARIANT_TRUE)
+ return 0;
+ return 1;
+}
+
+typedef struct MonoComObject MonoComObject;
+
+typedef struct
+{
+ int (STDCALL *QueryInterface)(MonoComObject* pUnk, gpointer riid, gpointer* ppv);
+ int (STDCALL *AddRef)(MonoComObject* pUnk);
+ int (STDCALL *Release)(MonoComObject* pUnk);
+ int (STDCALL *get_ITest)(MonoComObject* pUnk, MonoComObject* *ppUnk);
+ int (STDCALL *SByteIn)(MonoComObject* pUnk, char a);
+ int (STDCALL *ByteIn)(MonoComObject* pUnk, unsigned char a);
+ int (STDCALL *ShortIn)(MonoComObject* pUnk, short a);
+ int (STDCALL *UShortIn)(MonoComObject* pUnk, unsigned short a);
+ int (STDCALL *IntIn)(MonoComObject* pUnk, int a);
+ int (STDCALL *UIntIn)(MonoComObject* pUnk, unsigned int a);
+ int (STDCALL *LongIn)(MonoComObject* pUnk, LONGLONG a);
+ int (STDCALL *ULongIn)(MonoComObject* pUnk, ULONGLONG a);
+ int (STDCALL *FloatIn)(MonoComObject* pUnk, float a);
+ int (STDCALL *DoubleIn)(MonoComObject* pUnk, double a);
+ int (STDCALL *ITestIn)(MonoComObject* pUnk, MonoComObject* pUnk2);
+ int (STDCALL *ITestOut)(MonoComObject* pUnk, MonoComObject* *ppUnk);
+} MonoIUnknown;
+
+struct MonoComObject
+{
+ MonoIUnknown* vtbl;
+ int m_ref;
+};
+
+DEFINE_GUID(IID_ITest, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);
+DEFINE_GUID(IID_IMonoUnknown, 0, 0, 0, 0xC0, 0, 0, 0, 0, 0, 0, 0x46);
+DEFINE_GUID(IID_IMonoDispatch, 0x00020400, 0, 0, 0xC0, 0, 0, 0, 0, 0, 0, 0x46);
+
+int STDCALL MonoQueryInterface(MonoComObject* pUnk, gpointer riid, gpointer* ppv)
+{
+ *ppv = NULL;
+ if (!memcmp(riid, &IID_IMonoUnknown, sizeof(GUID))) {
+ *ppv = pUnk;
+ return S_OK;
+ }
+ else if (!memcmp(riid, &IID_ITest, sizeof(GUID))) {
+ *ppv = pUnk;
+ return S_OK;
+ }
+ else if (!memcmp(riid, &IID_IMonoDispatch, sizeof(GUID))) {
+ *ppv = pUnk;
+ return S_OK;
+ }
+ return E_NOINTERFACE;
+}
+
+int STDCALL MonoAddRef(MonoComObject* pUnk)
+{
+ return ++(pUnk->m_ref);
+}
+
+int STDCALL MonoRelease(MonoComObject* pUnk)
+{
+ return --(pUnk->m_ref);
+}
+
+int STDCALL SByteIn(MonoComObject* pUnk, char a)
+{
+ return S_OK;
+}
+
+int STDCALL ByteIn(MonoComObject* pUnk, unsigned char a)
+{
+ return S_OK;
+}
+
+int STDCALL ShortIn(MonoComObject* pUnk, short a)
+{
+ return S_OK;
+}
+
+int STDCALL UShortIn(MonoComObject* pUnk, unsigned short a)
+{
+ return S_OK;
+}
+
+int STDCALL IntIn(MonoComObject* pUnk, int a)
+{
+ return S_OK;
+}
+
+int STDCALL UIntIn(MonoComObject* pUnk, unsigned int a)
+{
+ return S_OK;
+}
+
+int STDCALL LongIn(MonoComObject* pUnk, LONGLONG a)
+{
+ return S_OK;
+}
+
+int STDCALL ULongIn(MonoComObject* pUnk, ULONGLONG a)
+{
+ return S_OK;
+}
+
+int STDCALL FloatIn(MonoComObject* pUnk, float a)
+{
+ return S_OK;
+}
+
+int STDCALL DoubleIn(MonoComObject* pUnk, double a)
+{
+ return S_OK;
+}
+
+int STDCALL ITestIn(MonoComObject* pUnk, MonoComObject *pUnk2)
+{
+ return S_OK;
+}
+
+int STDCALL ITestOut(MonoComObject* pUnk, MonoComObject* *ppUnk)
+{
+ return S_OK;
+}
+
+int STDCALL get_ITest(MonoComObject* pUnk, MonoComObject* *ppUnk)
+{
+ return S_OK;
+}
+
+static void create_com_object (MonoComObject** pOut)
+{
+ *pOut = g_new0 (MonoComObject, 1);
+ (*pOut)->vtbl = g_new0 (MonoIUnknown, 1);
+
+ (*pOut)->m_ref = 1;
+ (*pOut)->vtbl->QueryInterface = MonoQueryInterface;
+ (*pOut)->vtbl->AddRef = MonoAddRef;
+ (*pOut)->vtbl->Release = MonoRelease;
+ (*pOut)->vtbl->SByteIn = SByteIn;
+ (*pOut)->vtbl->ByteIn = ByteIn;
+ (*pOut)->vtbl->ShortIn = ShortIn;
+ (*pOut)->vtbl->UShortIn = UShortIn;
+ (*pOut)->vtbl->IntIn = IntIn;
+ (*pOut)->vtbl->UIntIn = UIntIn;
+ (*pOut)->vtbl->LongIn = LongIn;
+ (*pOut)->vtbl->ULongIn = ULongIn;
+ (*pOut)->vtbl->FloatIn = FloatIn;
+ (*pOut)->vtbl->DoubleIn = DoubleIn;
+ (*pOut)->vtbl->ITestIn = ITestIn;
+ (*pOut)->vtbl->ITestOut = ITestOut;
+ (*pOut)->vtbl->get_ITest = get_ITest;
+}
+
+static MonoComObject* same_object = NULL;
+
+STDCALL int
+mono_test_marshal_com_object_create(MonoComObject* *pUnk)
+{
+ create_com_object (pUnk);
+
+ if (!same_object)
+ same_object = *pUnk;
+
+ return 0;
+}
+
+STDCALL int
+mono_test_marshal_com_object_same(MonoComObject* *pUnk)
+{
+ *pUnk = same_object;
+
+ return 0;
+}
+
+STDCALL int
+mono_test_marshal_com_object_destroy(MonoComObject *pUnk)
+{
+ int ref = --(pUnk->m_ref);
+ g_free(pUnk->vtbl);
+ g_free(pUnk);
+
+ return ref;
+}
+
+STDCALL int
+mono_test_marshal_com_object_ref_count(MonoComObject *pUnk)
+{
+ return pUnk->m_ref;
+}
+
+STDCALL int
+mono_test_marshal_ccw_itest (MonoComObject *pUnk)
+{
+ int hr = 0;
+ MonoComObject* pTest;
+
+ if (!pUnk)
+ return 1;
+
+ hr = pUnk->vtbl->SByteIn (pUnk, -100);
+ if (hr != 0)
+ return 2;
+ hr = pUnk->vtbl->ByteIn (pUnk, 100);
+ if (hr != 0)
+ return 3;
+ hr = pUnk->vtbl->ShortIn (pUnk, -100);
+ if (hr != 0)
+ return 4;
+ hr = pUnk->vtbl->UShortIn (pUnk, 100);
+ if (hr != 0)
+ return 5;
+ hr = pUnk->vtbl->IntIn (pUnk, -100);
+ if (hr != 0)
+ return 6;
+ hr = pUnk->vtbl->UIntIn (pUnk, 100);
+ if (hr != 0)
+ return 7;
+ hr = pUnk->vtbl->LongIn (pUnk, -100);
+ if (hr != 0)
+ return 8;
+ hr = pUnk->vtbl->ULongIn (pUnk, 100);
+ if (hr != 0)
+ return 9;
+ hr = pUnk->vtbl->FloatIn (pUnk, 3.14f);
+ if (hr != 0)
+ return 10;
+ hr = pUnk->vtbl->DoubleIn (pUnk, 3.14);
+ if (hr != 0)
+ return 11;
+ hr = pUnk->vtbl->ITestIn (pUnk, pUnk);
+ if (hr != 0)
+ return 12;
+ hr = pUnk->vtbl->ITestOut (pUnk, &pTest);
+ if (hr != 0)
+ return 13;
+
+ return 0;
+}
+
+
+#endif //NOT_YET