有许多如何使用BSTR *参数调用IDispatch :: Invoke的示例.我可以将其与其他许多“ 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);
解决方法:
你们都处在正确的轨道上. @HansPassant的评论向我指出了“额头巴掌”“ eureka”的时刻,他的猜测是另一个参数.第一和第二参数的类型不同.对于:: Invoke反向传递,它们实际上是第二和第三参数.因此,它实际上是在类型不匹配的“ 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;