4

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 

マネージド オブジェクトからマーシャリングするアンマネージド バリアントを作成する必要があることを理解しています。これを行う方法について何か提案はありますか?

4

1 に答える 1