You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++中try块内抛出的异常未被捕获的问题排查

问题分析:try/catch未捕获COM异常的原因及解决办法

核心原因:异常类型不匹配

你的catch块仅捕获std::exception类型,但COM智能指针_com_ptr_t抛出的是**_com_error异常**——这个类并不继承自std::exception,因此当前的catch逻辑无法捕获到它。从堆栈跟踪也能看到,异常来自_com_raise_error函数,这是COM智能指针在调用失败时抛出_com_error的入口。

另外还有一个潜在问题:你没有检查pXS.CreateInstance的返回值hr,如果XMLSchemaCache60实例创建失败,pXS会是无效指针,此时调用pXS->add时,_com_ptr_t的operator->会直接抛出异常。

解决步骤

  • 捕获正确的异常类型:添加针对_com_error的catch块
  • 检查COM对象创建结果:确保pXS实例创建成功后再调用其方法
  • 优化代码细节:手动释放SysAllocString分配的BSTR,避免内存泄漏

修改后的代码示例

#import <msxml6.dll>
using namespace MSXML2;

// ...

IXMLDOMSchemaCollectionPtr   pXS;
IXMLDOMDocument2Ptr          pXD = NULL;
MSXML2::IXMLDOMParseErrorPtr pErr = NULL;
_bstr_t                      strResult = "";

HRESULT hr = pXS.CreateInstance(__uuidof(XMLSchemaCache60));
if (FAILED(hr)) {
    std::cerr << "创建XMLSchemaCache60实例失败,HRESULT: 0x" << std::hex << hr << std::endl;
    return; // 或处理错误后退出
}

CComVariant  xsd_file;
_bstr_t bstrXSD(L"test_xsd.xsd");

BSTR empty_bstr = SysAllocString(L"urn:namespace");

try {
    hr = pXS->add(_bstr_t(""), bstrXSD);
}
catch (const _com_error& e) {
    std::cerr << "COM错误: " << e.ErrorMessage() << std::endl;
    std::cerr << "错误码HRESULT: 0x" << std::hex << e.Error() << std::endl;
}
catch (const std::exception& e) {
    std::cerr << "标准异常: " << e.what() << std::endl;
}

// 释放分配的BSTR
SysFreeString(empty_bstr);

额外说明

  • _com_error提供了Error()获取HRESULT错误码、ErrorMessage()获取错误描述,可帮助排查具体问题(比如XSD文件不存在、格式错误等)
  • 如果不想使用异常处理,可修改#import指令禁用异常:#import <msxml6.dll> no_exceptions,此时智能指针会返回HRESULT而非抛出异常,需要手动检查每个调用的返回值

内容的提问来源于stack exchange,提问作者aprotiere

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 08:22:28