1

VB.NET から遅延バインディングを使用して呼び出したい COM コンポーネントがあります (面倒な Primary Interop Assembly - PIA メソッドを使用)。

COM メソッドの IDL 署名は次のようになります。

HRESULT Send([in]BSTR bstrRequestData,
             [out]VARIANT *pvbstrResponseData,
             [out]VARIANT *pvnExtCompCode,
             [out,retval]int *pnCompletionCode);

したがって、VB.NET 用語では 2 つの「ByRef」パラメーターと戻り値です。

私はこのメソッドを次のように呼び出そうとします:

Dim parameters(2) As Object
parameters(0) = "data"
parameters(1) = New Object()
parameters(2) = New Object()

Dim p As New ParameterModifier(3)
p(1) = True
p(2) = True
Dim parameterMods() As ParameterModifier = {p}

objReturn = MyObject.GetType().InvokeMember("Send", _
                                            BindingFlags.InvokeMethod, _
                                            Nothing, _
                                            MyObject, _
                                            parameters, _
                                            parameterMods, _
                                            Nothing, _
                                            Nothing)

これは例外で見事に失敗します: {"Invalid callee. (Exception from HRESULT: 0x80020010 (DISP_E_BADCALLEE))"}

これは、parameterMods 配列で何か間違ったことをしていることを意味すると思います。ParameterMods配列の値を「True」に設定してコメントアウトすると、機能するためです。もちろん、[out] パラメータであるパラメータは更新されないため、意図したとおりに機能しません。

メソッドにも戻り値があるため、他に考慮すべき点はありますか? MSDNの例は、例に戻り値がないことを除いて、私が行っていることとほとんど同じです。どんな助けでも大歓迎です。

4

1 に答える 1

1

1 つの問題は、引数と ParameterModifier 配列のサイズが異なることです。CLR/BCL がすべての引数を ParameterModifier と一致させることができるように、それらを一致させる必要があると思います。

PIA が署名の保存属性を使用して生成された場合、メソッドには実際には 3 つではなく 4 つの引数があります。配列を拡張して 4 つのメンバーを保持する必要があり、pnCompletionCode の戻り値は引数配列の最後のインデックスになりますコールが完了します。

また、なぜこの呼び出し方法を使用しているのか気になります。VB.Net を使用しているため、Option Explicit を無効にして VB レイト バインダーを使用しないでください。リフレクション コードを自分で書き出すよりもはるかに簡単です (また、奇妙なマーシャリング ルールを処理するため、通常はもう少し正確です)。

Option Explicit Off
...
Dim obj As Object = DirectCast(MyObject,Object)
obj.Send("data", new Object(), new Object())
于 2009-05-23T10:29:00.170 に答える