字符串的变体 * 引发未知异常
我使用此代码在 C++ 上的 IWebBrowser2 Web 浏览器中接收事件:
STDMETHODIMP AdviseSink::Invoke(DISPID dispIdMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS* pDispParams,
VARIANT* pVarResult,
EXCEPINFO* pExcepInfo,
UINT* puArgErr)
{
if (!pDispParams)
return DISP_E_PARAMNOTOPTIONAL;
switch (dispIdMember)
{
case DISPID_DOCUMENTCOMPLETE:
{
DocumentComplete(pVarResult);
return S_OK;
}
case DISPID_NAVIGATECOMPLETE2:
return S_OK;
default:
return DISP_E_MEMBERNOTFOUND;
}
return S_OK;
}
void DocumentComplete(VARIANT *url)
{
std::string strValue = (char*)_bstr_t(url);
}
调用 (void)DocumentComplete 时出现此错误:
*Webhost.exe 中 0x7c812afb 处未处理的异常:Microsoft C++ 异常:内存位置 0x0012ed50 处的 _com_error。*
如果注释DocumentComplete 上的行,它没有显示任何错误。另外 try..catch 块不会捕获异常。
我想做的是使用 Variant * url 将其与 std::string 进行比较。
我该怎么做?
I am using this code to sink events in a IWebBrowser2 webbrowser on c++:
STDMETHODIMP AdviseSink::Invoke(DISPID dispIdMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS* pDispParams,
VARIANT* pVarResult,
EXCEPINFO* pExcepInfo,
UINT* puArgErr)
{
if (!pDispParams)
return DISP_E_PARAMNOTOPTIONAL;
switch (dispIdMember)
{
case DISPID_DOCUMENTCOMPLETE:
{
DocumentComplete(pVarResult);
return S_OK;
}
case DISPID_NAVIGATECOMPLETE2:
return S_OK;
default:
return DISP_E_MEMBERNOTFOUND;
}
return S_OK;
}
void DocumentComplete(VARIANT *url)
{
std::string strValue = (char*)_bstr_t(url);
}
When calling (void)DocumentComplete I get this error:
*Unhandled exception at 0x7c812afb in webhost.exe: Microsoft C++ exception: _com_error at memory location 0x0012ed50.*
If comment the line on DocumentComplete, it doesn't show any errors. Also try..catch blocks doens't catch the exception.
What I am trying to do is to use Variant * url to compare it with a std::string.
How can I do this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您正在使用返回值([out] 参数)作为事件参数之一。这将导致 bstr_t 抛出 com_error 异常,因为 VARIANT 不包含 BSTR。
有关正确的 DocumentComplete 签名,请参阅 MSDN 文档 。
事件参数可从 pDispParams 获取,而不是从 pVarResult 获取。假设未使用命名参数调用它(并且此事件不应该如此),则 url 将在 pDispParams->rgvarg[0] 处可用,而窗口/框架将在 pDispParams->rgvarg[1] 处可用。 rgvarg 数组中参数的顺序与 idl 中声明的顺序相反。
如果可以的话,我建议改用 ATL 的 IDispEventSimpleImpl 用 C++ 实现 COM 事件接口,而不是自己实现 IDispatch。
You are using the return value (an [out] parameter) as one of the event parameters. This will cause bstr_t to throw a com_error exception because the VARIANT doesn't contain a BSTR.
See the MSDN documentation for the correct DocumentComplete signature.
The event parameters are available from pDispParams not pVarResult. Assuming that it's not called with named arguments (and this event shouldn't be), the url will be available at pDispParams->rgvarg[0] and the window/frame at pDispParams->rgvarg[1]. Parameters are in the opposite order in the rgvarg array as they're declared in the idl.
If you can, I recommend instead using ATL's IDispEventSimpleImpl to implement COM event interfaces in C++ instead of implementing IDispatch yourself.
http://msdn.microsoft.com/en- us/library/9k3ebasf(v=VS.100).aspx
_bstr_t
构造函数仅接受 VARIANT 的引用,而不是指向它的指针。http://msdn.microsoft.com/en-us/library/9k3ebasf(v=VS.100).aspx
the
_bstr_t
constructor takes only reference of VARIANT, instead of pointer to it.叶飞给出了一半的答案。另一半是,在获得 bstr 后,它将指向 Unicode 字符串而不是 ANSI 字符串。如果要获取 ANSI 字符串,则必须通过将字符串从 Unicode 转换为 ANSI 来实现,而不是通过转换指针来实现。
YeenFei gave half of the answer. The other half is that after you get your bstr, it will point to a Unicode string not to an ANSI string. If you want to get an ANSI string, you have to do it by converting the string from Unicode to ANSI, not by converting the pointer.