我正在使用 P/Invoke 从 C# 调用非托管 C 函数,并传递对象数组。在非托管代码中,我为 IDispatch 查询 IUnknown。这适用于简单的情况,但如果其中一个对象是数组本身,则获取 IDispatch 失败。
托管代码:
[DllImport("NativeDll.dll")]
static extern void TakesAnObjectArray(int len,
[MarshalAs(UnmanagedType.LPArray,
ArraySubType = UnmanagedType.IUnknown)]object[] a);
public static void exec1(int a, object b, string c)
{
Object[] info_array;
Object[] parameters_array;
parameters_array = new object[4];
parameters_array[0] = a;
parameters_array[1] = b;
parameters_array[2] = c;
parameters_array[3] = 55;
// THIS WORKS GREAT
TakesAnObjectArray(4, parameters_array);
info_array = new object[6];
info_array[0] = parameters_array;
// THIS DOESN'T
// I CAN'T GET IDISPATCH FOR THE 1ST 'OBJECT'
TakesAnObjectArray(6, info_array);
}
非托管代码:
void TakesAnObjectArray(int len, LPUNKNOWN p[])
{
HRESULT hr;
for (int i=0; i<len; i++)
{
IDispatch *disp = NULL;
hr = p[i]->QueryInterface(IID_IDispatch, (void**)&disp);
}
}
QueryInterface 大部分时间都是成功的。但是,如果托管对象实际上是“System.Object[]”,则无法获得 IDispatch 接口(hr = 0x80004002 = E_NOINTERFACE = '不支持此类接口')。
我可以以某种方式使用 MarshalAs(...) 来解决这个问题吗?还是有另一种方法可以让它发挥作用?