としてIオブジェクトの配列を渡し、C位からアンマネージC関数を呼び出すためにP /呼び出しを使用しているのマーシャリング。 アンマネージドコードでは、IUnknown for IDispatchをクエリします。 これは単純なケースでは機能しますが、オブジェクトの1つが配列そのものであれば、IDispatchの取得に失敗します。管理ツーアンマネージ「オブジェクトは[]」の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を取得し、typeInfo-> GetDocumentation()というITypeInfoを取得しました。次に、 'GetIDsOfNames'と 'Invoke'を使用して 'ToString'を実行し、正しい情報を取得しました。 SAFEARRAYアプローチを試してみましょう。 – zvikam
Cool。 SAFEARRAYとしてのマーシャリングが機能し、メインアレイとサブアレイのすべての要素が得られました。 さらに詳しい情報を問い合わせることができる複雑なオブジェクトに対して、私はVARIANTのVT_UNKNOWNを取得しました。 – zvikam