我有一个COM组件,我想使用VB.NET的后期绑定调用(使用痛苦的主Interop程序集 - 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)
这在例外情况下失败,但是异常:{“被调用者无效。(HRESULT异常:0x80020010(DISP_E_BADCALLEE))”}
我认为这意味着我在我的parameterMods数组中做错了。因为如果我注释掉将ParameterMods数组的任何值设置为'True' - 它就可以了。它当然不会更新[out]参数的参数,因此它无法正常工作。
还有其他需要考虑的因为该方法也有返回值吗? MSDN example几乎完全正是我正在做的事情,除了示例没有返回值。任何帮助表示赞赏。
答案 0 :(得分:0)
一个问题是您的参数和ParameterModifier数组具有不同的大小。我相信它们必须匹配,以便CLR / BCL可以使用ParameterModifier匹配每个参数。
如果使用保留签名属性生成PIA,则该方法实际上有4个参数而不是3.您需要扩展数组以容纳4个成员,并且pnCompletionCode的返回值将在最后一个索引中。调用完成后的参数数组。
另外,我很好奇你为什么要使用这种调用方法。由于您使用的是VB.Net,为什么不禁用Option Explicit并使用VB后期绑定器。这比自己编写反射代码容易得多(并且通常会更正确,因为它会处理奇怪的编组规则)。
Option Explicit Off
...
Dim obj As Object = DirectCast(MyObject,Object)
obj.Send("data", new Object(), new Object())