我使用P/Invoke從C#調用非託管C函數,傳遞一個對象數組。 在非託管代碼中,我查詢IDispatch的IUnknown。 這適用於簡單情況,但如果其中一個對象是數組本身,則獲取IDispatch失敗。'object []'託管到非託管封送作爲IUnknown
託管代碼:
[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(...)以某種方式解決這個問題嗎? 或者還有其他方法可以使這個工作?
謝謝你的評論。 我實際上設法做了很多與IUnknown:得到一個IDispatch,得到ITypeInfo,調用typeInfo-> GetDocumentation()來獲取類型名稱。然後使用'GetIDsOfNames'和'Invoke'來執行'ToString',甚至得到正確的信息... 我會嘗試SAFEARRAY方法,看看它是否更好。 – zvikam 2012-04-25 11:57:06
很酷。以SAFEARRAY的方式進行封送,我得到了主陣列的所有元素以及子陣列。 我甚至爲複雜的對象獲得了VARIANT的VT_UNKNOWN,我可以查詢更多信息。 – zvikam 2012-04-25 13:01:54