如何使用所需的BSTR *参数正确调用IDispatch :: Invoke

时间:2014-07-09 17:34:10

标签: c++ com invoke bstr idispatch

有许多如何使用BSTR *参数调用IDispatch :: Invoke的示例。我和其他许多人一起工作了#Some; SomeType *"参数,但无论我尝试什么,我要么得到类型不匹配的HRESULT,E_OUTOFMEMORY或访问冲突。在我看来,我正在做一些错误的记忆,但我正在遵循我发现的不同的例子......作为旁注,最后的" [out] UINT puArgErr"参数永远不会填充导致问题的参数索引。但是,我知道它是BSTR 类型的第三个参数(我已经成功地调用了另一个采用前两个参数的方法。)

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

*

//...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 *参数的其他例子时会发生这种情况......此外我还有许多其他成功调用IDispatch :: Invoke但这个BTR *让我停下来。

绝望,请帮助!

增加:

IDL是:         [ID(0x00000171)]         简短的GetCategory(                         简短的nIndx,                         短* nCat,                         BSTR * bszName);

1 个答案:

答案 0 :(得分:3)

你们都在正确的轨道上。 @HansPassant的评论向我指出了“额头一击”“尤里卡”的一刻,他猜测它会炸掉一个不同的参数。第一和第二参数是不同类型的。反向传递:: Invoke它们实际上是第2和第3个参数。所以它实际上是炸掉了我的“1st”参数,类型不匹配。

在我最初的概念验证版本中,我手动传递参数,我故意按照IDispatch :: Invoke的要求以相反的顺序正确传递参数。在将此转换为更通用的方法的过程中,循环通过从调用者传递的参数数组,当我将它们返回到调用应用程序时,我在调用IDispatch :: Invoke之后反转了参数顺序,但是,我忘了反转他们在调用Invoke之前的路上。

神圣的“你知道什么”这些错误对于没有这方面经验的人来说是如此深奥!

一旦我修改了参数的顺序,一切都表现得与预期完全一致。当然,我的问题中的“变化1”是处理BSTR *参数的正确方法。为清楚起见,这里是初始化由IDispatch :: Invoke调用的BSTR *参数的变量参数的正确方法(在我的例子中还有2个其他参数未在此处显示)

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 | BT_BYREF;
v[0].pbstrVal = &val;