2007-09-25 Zoltan Varga <vargaz@gmail.com>
[mono.git] / mono / tests / libtest.c
index 96fd60c2958520a3e231351b1b7e2eaab6c23851..731382d0b0a01aa26e5e61c9ddcfe7b2451dbe60 100644 (file)
@@ -7,6 +7,7 @@
 
 #ifdef WIN32
 #include <windows.h>
+#include "initguid.h"
 #endif
 
 #ifdef WIN32
@@ -361,9 +362,7 @@ mono_test_ref_vtype (int a, simplestruct *ss, int b, RefVTypeDelegate func)
                ss->c = 1;
                ss->d = "TEST2";
 
-               printf ("A1\n");
                return func (a, ss, b);
-               printf ("A2\n");
        }
 
        return 1;
@@ -417,6 +416,8 @@ 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;
@@ -734,6 +735,29 @@ mono_test_marshal_delegate7 (SimpleDelegate7 delegate)
        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
@@ -798,6 +822,17 @@ mono_test_marshal_stringbuilder (char *s, int n)
        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;
 }
 
@@ -811,8 +846,8 @@ mono_test_marshal_stringbuilder_unicode (gunichar2 *s, int n)
        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);
@@ -952,6 +987,35 @@ mono_test_byvalstr_check (ByValStrStruct* data, char* correctString)
        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)
 {
@@ -1117,20 +1181,26 @@ string_marshal_test3 (char *str)
 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;
 }
@@ -1303,12 +1373,37 @@ typedef struct
        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;
@@ -1430,6 +1525,21 @@ mono_test_marshal_pass_out_custom (int i, guint32 **ptr, int j)
        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)
 {
@@ -1487,6 +1597,21 @@ mono_test_marshal_pass_return_custom_null_in_delegate (PassReturnPtrDelegate del
        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
@@ -1777,6 +1902,24 @@ mono_test_marshal_out_array_delegate (int *arr, int len, ArrayDelegate del)
                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)
 {
@@ -1834,6 +1977,97 @@ 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
  */
@@ -1855,6 +2089,21 @@ mono_test_marshal_bstr_out(BSTR* bstr)
        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)
 {
@@ -1943,6 +2192,22 @@ mono_test_marshal_variant_in_bstr(VARIANT variant)
        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)
 {
@@ -2042,4 +2307,521 @@ mono_test_marshal_variant_out_bstr(VARIANT* variant)
        return 0;
 }
 
-#endif
+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