IDispatch をサポートするレガシー COM オブジェクトの遅延バインディングに Invoke を使用しています。.NET の Type.GetMethod Type.InvokeMember がこれらのオブジェクトで機能しないように見えるため、これが必要なようです。
次のコードは、オブジェクトからプロパティを取得する場合に正常に機能します。呼び出し元は、プロパティ名を文字列として渡し、遅延バインディングでプロパティ値を取得します。このクラスは、コンストラクターでオブジェクトを受け取り、オブジェクトへのインターフェイス ポインターとして this.idisp (および this.lcid) を設定します (批評を歓迎します!)。
public object InvokeGet(string propertyName)
{
int id = GetDispID(propertyName);
IntPtr[] pArgErr = default(IntPtr[]);
object pVarResult;
System.Runtime.InteropServices.ComTypes.DISPPARAMS pDispParams = default(System.Runtime.InteropServices.ComTypes.DISPPARAMS);
System.Runtime.InteropServices.ComTypes.EXCEPINFO pExcepInfo = default(System.Runtime.InteropServices.ComTypes.EXCEPINFO);
Guid guid = new Guid();
int result = this.idisp.Invoke(id, ref guid, (uint)this.lcid,
(ushort)System.Runtime.InteropServices.ComTypes.INVOKEKIND.INVOKE_PROPERTYGET,
ref pDispParams, out pVarResult, ref pExcepInfo, pArgErr);
if (result != 0)
{
throw new ArgumentException(string.Format("Error invoking property: {0}. COM error code is {1}", propertyName, result));
}
return pVarResult;
}
私は今、同等のセッターを書こうとしています。
public void InvokeSet(string propertyName, object newValue)
ただし、Dispatch パラメータを C# でパッケージ化する方法がわかりません。
つまり、構造を設定する方法:
System.Runtime.InteropServices.ComTypes.DISPPARAMS
マネージド オブジェクトからマーシャリングするアンマネージド バリアントを作成する必要があることを理解しています。これを行う方法について何か提案はありますか?