m->csig = csig;
}
+static MonoMarshalSpec*
+cominterop_get_ccw_default_mspec (const MonoType *param_type)
+{
+ MonoMarshalVariant elem_type;
+ MonoMarshalNative native;
+ MonoMarshalSpec *result;
+
+ switch (param_type->type) {
+ case MONO_TYPE_OBJECT:
+ native = MONO_NATIVE_STRUCT;
+ break;
+ case MONO_TYPE_STRING:
+ native = MONO_NATIVE_BSTR;
+ break;
+ case MONO_TYPE_CLASS:
+ native = MONO_NATIVE_INTERFACE;
+ break;
+ case MONO_TYPE_BOOLEAN:
+ native = MONO_NATIVE_VARIANTBOOL;
+ break;
+ case MONO_TYPE_SZARRAY:
+ /* object[] -> SAFEARRAY(VARIANT) */
+ native = MONO_NATIVE_SAFEARRAY;
+ if (param_type->data.array->eklass == mono_defaults.object_class)
+ elem_type = MONO_VARIANT_VARIANT;
+ else
+ return NULL;
+ break;
+ default:
+ return NULL;
+ }
+
+ result = g_new0 (MonoMarshalSpec, 1);
+ result->native = native;
+ if (native == MONO_NATIVE_SAFEARRAY)
+ result->data.safearray_data.elem_type = elem_type;
+
+ return result;
+}
+
/**
* cominterop_get_ccw_checked:
* @object: a pointer to the object
mspecs [mspec_index] = mspecs [param_index];
if (mspecs[mspec_index] == NULL) {
- if (sig_adjusted->params[param_index]->type == MONO_TYPE_OBJECT) {
- mspecs[mspec_index] = g_new0 (MonoMarshalSpec, 1);
- mspecs[mspec_index]->native = MONO_NATIVE_STRUCT;
- }
- else if (sig_adjusted->params[param_index]->type == MONO_TYPE_STRING) {
- mspecs[mspec_index] = g_new0 (MonoMarshalSpec, 1);
- mspecs[mspec_index]->native = MONO_NATIVE_BSTR;
- }
- else if (sig_adjusted->params[param_index]->type == MONO_TYPE_CLASS) {
- mspecs[mspec_index] = g_new0 (MonoMarshalSpec, 1);
- mspecs[mspec_index]->native = MONO_NATIVE_INTERFACE;
- }
- else if (sig_adjusted->params[param_index]->type == MONO_TYPE_BOOLEAN) {
- mspecs[mspec_index] = g_new0 (MonoMarshalSpec, 1);
- mspecs[mspec_index]->native = MONO_NATIVE_VARIANTBOOL;
- }
+ mspecs[mspec_index] = cominterop_get_ccw_default_mspec (sig_adjusted->params[param_index]);
} else {
/* increase SizeParamIndex since we've added a param */
if (sig_adjusted->params[param_index]->type == MONO_TYPE_ARRAY ||
/* move return spec to last param */
if (!preserve_sig && !MONO_TYPE_IS_VOID (sig->ret)) {
- if (mspecs [0] == NULL) {
- if (sig_adjusted->params[sig_adjusted->param_count-1]->type == MONO_TYPE_OBJECT) {
- mspecs[0] = g_new0 (MonoMarshalSpec, 1);
- mspecs[0]->native = MONO_NATIVE_STRUCT;
- }
- else if (sig_adjusted->params[sig_adjusted->param_count-1]->type == MONO_TYPE_STRING) {
- mspecs[0] = g_new0 (MonoMarshalSpec, 1);
- mspecs[0]->native = MONO_NATIVE_BSTR;
- }
- else if (sig_adjusted->params[sig_adjusted->param_count-1]->type == MONO_TYPE_CLASS) {
- mspecs[0] = g_new0 (MonoMarshalSpec, 1);
- mspecs[0]->native = MONO_NATIVE_INTERFACE;
- }
- else if (sig_adjusted->params[sig_adjusted->param_count-1]->type == MONO_TYPE_BOOLEAN) {
- mspecs[0] = g_new0 (MonoMarshalSpec, 1);
- mspecs[0]->native = MONO_NATIVE_VARIANTBOOL;
- }
- }
+ if (mspecs [0] == NULL)
+ mspecs[0] = cominterop_get_ccw_default_mspec (sig_adjusted->params[sig_adjusted->param_count-1]);
mspecs [sig_adjusted->param_count] = mspecs [0];
mspecs [0] = NULL;
[MethodImplAttribute (MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void ArrayIn ([In, MarshalAs (UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_VARIANT)] object[] array);
[MethodImplAttribute (MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
+ void ArrayIn2 ([In] object[] array);
+ [MethodImplAttribute (MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs (UnmanagedType.Interface)]
TestDefaultInterfaceClass1 GetDefInterface1();
[MethodImplAttribute (MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
int IntOut (out int val);
[MethodImplAttribute (MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
int ArrayIn ([In, MarshalAs (UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_VARIANT)] object[] array);
+ [MethodImplAttribute (MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
+ int ArrayIn2 ([In] object[] array);
}
[System.Runtime.InteropServices.GuidAttribute ("00000000-0000-0000-0000-000000000002")]
[MethodImplAttribute (MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public virtual extern void ArrayIn ([In, MarshalAs (UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_VARIANT)] object[] array);
[MethodImplAttribute (MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
+ public virtual extern void ArrayIn2 ([In] object[] array);
+ [MethodImplAttribute (MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public virtual extern TestDefaultInterfaceClass1 GetDefInterface1();
[MethodImplAttribute (MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public virtual extern TestDefaultInterfaceClass2 GetDefInterface2();
return 444;
}
+
+ public int ArrayIn2(object[] array)
+ {
+ return ArrayIn(array);
+ }
}
public class ManagedTest : ITest
status = 444;
}
+ public void ArrayIn2(object[] array)
+ {
+ ArrayIn(array);
+ }
+
public TestDefaultInterfaceClass1 GetDefInterface1()
{
return new TestDefaultInterfaceClass1();
int (STDCALL *Return22NoICall)(MonoComObject* pUnk);
int (STDCALL *IntOut)(MonoComObject* pUnk, int *a);
int (STDCALL *ArrayIn)(MonoComObject* pUnk, void *array);
+ int (STDCALL *ArrayIn2)(MonoComObject* pUnk, void *array);
int (STDCALL *GetDefInterface1)(MonoComObject* pUnk, MonoDefItfObject **iface);
int (STDCALL *GetDefInterface2)(MonoComObject* pUnk, MonoDefItfObject **iface);
} MonoIUnknown;
}
LIBTEST_API int STDCALL
+ArrayIn2(MonoComObject* pUnk, void *array)
+{
+ return S_OK;
+}
+
+LIBTEST_API int STDCALL
GetDefInterface1(MonoComObject* pUnk, MonoDefItfObject **obj)
{
return S_OK;
(*pOut)->vtbl->Return22NoICall = Return22NoICall;
(*pOut)->vtbl->IntOut = IntOut;
(*pOut)->vtbl->ArrayIn = ArrayIn;
+ (*pOut)->vtbl->ArrayIn2 = ArrayIn2;
(*pOut)->vtbl->GetDefInterface1 = GetDefInterface1;
(*pOut)->vtbl->GetDefInterface2 = GetDefInterface2;
}
SafeArrayPutElement(array, &index, &var);
ret = pUnk->vtbl->ArrayIn (pUnk, (void *)array);
+ if (!ret)
+ ret = pUnk->vtbl->ArrayIn2 (pUnk, (void *)array);
SafeArrayDestroy(array);