如何正确调用IDispatch :: Invoke与所需的BSTR *参数 [英] How to properly call IDispatch::Invoke with a required BSTR* parameter

查看:134
本文介绍了如何正确调用IDispatch :: Invoke与所需的BSTR *参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有许多如何使用BSTR *参数调用IDispatch :: Invoke的示例。我可以将其与其他许多 SomeType *参数一起使用,但是无论我如何尝试,我都会得到类型不匹配的HRESULT,E_OUTOFMEMORY或访问冲突。在我看来,我在内存方面做错了事,但是我在遵循发现的不同示例...作为补充说明,最后的[[out] UINT puArgErr参数永远不会填充参数索引,造成了问题。但是,我知道这是BSTR类型的第三个参数(我已经成功调用了另一个接受前两个参数的方法。)

There are many examples of how to call IDispatch::Invoke with a BSTR* parameter. I have this working with many other "SomeType*" parameter but no matter what I try, I either get HRESULT of Type Mismatch, E_OUTOFMEMORY or an access violation. It seems to me I am doing something wrong with memory but I am following the different examples I have found... As a side note, the final "[out] UINT puArgErr" argument is never filled with the argument index that is causing the problem. However, I know it is the 3rd argument of type BSTR (I have successfully called another method that takes the 2 previous arguments.)

VARIANTARG* v = new VARIANTARG[3];
//...Init my first 2 args
//Code omitted for initializing args 1 and 2 and wrapping everything up to call IDispatch->Invoke

//... Variation 1
VariantInit(v[2]);
BSTR val = SysAllocString(L"");
v[2].vt = VT_BSTR | BT_BYREF;
v[2].pbstrVal = &val;
//When I wrap everything up in the call to IDispatch::Invoke 
//this yields a HRESULT of Type Mismatch

*

//...Variation 2
VariantInit(v[2]);
BSTR val = SysAllocString(L"");
v[2].vt = VT_BSTR | BT_BYREF;
v[2].bstrVal = val;
//When I wrap everything up in the call to IDispatch::Invoke 
//this yields a HRESULT of E_OUTOFMEMORY

$的HRESULT b
$ b

*

*

//...Variation 3
VariantInit(v[2]);
BSTR val = SysAllocString(L"RandomStringLargerThanTheMethodWillPlaceInTheOutParam");
v[2].vt = VT_BSTR | BT_BYREF;
v[2].bstrVal = val;
//When I wrap everything up in the call to IDispatch::Invoke 
//this yields an access violation

*

//...Variation 4
VariantInit(v[2]);
BSTR val = 0;
v[2].vt = VT_BSTR | BT_BYREF;
v[2].bstrVal = val;
//When I wrap everything up in the call to IDispatch::Invoke 
//this yields and HRESULT of 0x800706f4 A null reference pointer 
//was passed to the stub. 

我不明白为什么当我关注其他BTR *参数示例时会发生这种情况。 。

I don't understand why when I am following other examples of BTR* parameters this is happening... Furthermore I have many other successful calls to IDispatch::Invoke but this BTR* has me ground to a halt.

绝望,请帮助!

加法:

IDL为:
[id(0x00000171)]
short GetCategory(
short nIndx,
short * nCat,
BSTR * bszName);

IDL is: [id(0x00000171)] short GetCategory( short nIndx, short* nCat, BSTR* bszName);

推荐答案

正确的轨道上。 @HansPassant的评论向我指出了额头巴掌 eureka的时刻,他的猜测是另一个参数。第一和第二参数的类型不同。对于:: Invoke反向传递,它们实际上是第二和第三参数。因此它实际上是在类型不匹配的 1st参数上爆炸的。

You were all on the right track. @HansPassant comment pointed me to the "forehead-slap" "eureka" moment with his surmising about it blowing up on a different parameter. The 1st and 2nd parameters are of a different type. Passed in reverse for ::Invoke they are actually the 2nd and 3rd parameters. So it was actually blowing up on my "1st" parameter with a type mismatch.

在最初的概念验证版本中,我是手动传递参数的,所以我故意按照IDispatch :: Invoke要求的相反顺序正确传递参数。在将其转换为更通用的方法的过程中,遍历从调用方传递的参数数组,在将IDispatch :: Invoke调用返回给调用应用程序后,我颠倒了参数顺序,但是,我忘记了反向

In my initial proof-of-concept version I was manually passing parameters and I was purposefully passing the parameters correctly in reverse order as required by IDispatch::Invoke. In the process of converting this to a more generic approach looping through an array of parameters passed from the caller I reversed the parameter order AFTER the call to IDispatch::Invoke when I am returning them to the calling app, however, I forgot to reverse them on the way in prior to the call to Invoke.

圣洁的你知道什么错误对于没有大量经验的人来说是如此深奥!

Holy "you-know-what" the errors are so esoteric to someone without a ton of experience with this stuff!

一旦我固定了参数的顺序,所有行为就完全符合预期了。我的问题中的变量1当然是处理BSTR *参数的正确方法。为了清楚起见,这是为IDispatch :: Invoke调用的BSTR *参数初始化变量参数的正确方法(在我的情况下,这里未显示2个其他参数)

Once I fixed the order of parameters everything behaved exactly as expected. "Variation 1" from my question was, of course, the correct way to handle the BSTR* parameter. For clarity, here is the correct way to initialize a variant parameter for a BSTR* parameter being called by IDispatch::Invoke (in my case there are 2 other parameters that are not shown here)

VARIANTARG* v = new VARIANTARG[3];
//...Init my first 2 args IN REVERSE (not shown here)

//Init my third arg which is the BSTR* parameter
VariantInit(v[0]);
BSTR val = SysAllocString(L"");
v[0].vt = VT_BSTR | VT_BYREF;
v[0].pbstrVal = &val;

这篇关于如何正确调用IDispatch :: Invoke与所需的BSTR *参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆