如何使用后期绑定来调用带有 ByRef 参数的方法
我有一个 COM 组件,我想使用 VB.NET 的后期绑定来调用它(使用痛苦的主互操作程序集 - PIA 方法)
COM 方法的 IDL 签名如下所示:
HRESULT Send([in]BSTR bstrRequestData,
[out]VARIANT *pvbstrResponseData,
[out]VARIANT *pvnExtCompCode,
[out,retval]int *pnCompletionCode);
So 2 'ByRef'parameters in VB.NET lingo ,和一个返回值。
我尝试像这样调用这个方法:
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)
这会失败并出现异常:{“无效的被调用者。(HRESULT的异常:0x80020010(DISP_E_BADCALLEE))”}
我认为这意味着我在我的parameterMods数组中做错了什么。 因为如果我注释掉将 ParameterMods 数组的任何值设置为“True” - 它就会起作用。 它当然不会更新[out]参数,因此它无法按预期工作。
既然该方法也有返回值,还需要考虑其他什么吗? MSDN 示例 几乎完全符合我的要求这样做,但示例没有返回值。 任何帮助表示赞赏。
I have a COM component that I want to call using late-binding from VB.NET (using the painful Primary Interop Assembly - PIA method)
My IDL signature for the COM method looks like:
HRESULT Send([in]BSTR bstrRequestData,
[out]VARIANT *pvbstrResponseData,
[out]VARIANT *pvnExtCompCode,
[out,retval]int *pnCompletionCode);
So 2 'ByRef' parameters in VB.NET lingo, and a return value.
I attempt to invoke this method like so:
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)
This fails spectactularly with an exception: {"Invalid callee. (Exception from HRESULT: 0x80020010 (DISP_E_BADCALLEE))"}
I assume this means I'm doing something wrong in my parameterMods array. Because if I comment out setting any value of the ParameterMods array to 'True' - it works. It of course doesnt update the parameters that are [out] parameters and so it's not working as intended.
Is there something else to consider since the method also has a return value? The MSDN example pretty much does exactly what I am doing, with the exception that example did not have a return value. Any help is appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
一个问题是您的参数和 ParameterModifier 数组的大小不同。 我相信它们必须匹配,以便 CLR/BCL 可以将每个参数与 ParameterModifier 匹配。
如果 PIA 是使用保留签名属性生成的,则该方法实际上有 4 个参数,而不是 3 个。您需要扩展数组以容纳 4 个成员,并且 pnCompletionCode 的返回值将位于参数数组的最后一个索引中呼叫完成。
我也很好奇你为什么使用这种调用方法。 既然您使用的是 VB.Net,为什么不禁用 Option Explicit 并使用 VB Late Binder。 这比自己编写反射代码要容易得多(并且通常会更正确一点,因为它将处理奇怪的编组规则)。
One issue is that your argument and ParameterModifier arrays have different sizes. I believe they must match up such so that the CLR/BCL can match every argument with a ParameterModifier.
If the PIA was generated with the preserve signature attributes, the method actually has 4 arguments instead of 3. You'll need to extend the arrays to hold 4 members and the return value of pnCompletionCode will be in the last index of the argument array after the call completes.
Also I'm curious why you're using this method of invocation. Since you're using VB.Net why not disable Option Explicit and use the VB late binder. It's much easier than writing out the reflection code yourself (and will typically be a bit more correct because it will deal with weird marshalling rules).