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

C++调用Python(Boost.Python):如何判断抛出对象类型?

在C++的catch(...)分支中判断抛出对象的类型

通用方法:利用std::current_exception()重新捕获

在catch(...)分支里,你可以重新抛出异常并尝试针对性捕获,以此识别类型,但这种方式对非多态类型(无虚函数的类)效果有限:

catch(...) {
    try {
        std::rethrow_exception(std::current_exception());
    }
    catch(const std::exception& e) {
        std::cout << "异常类型:" << typeid(e).name() << ",信息:" << e.what() << std::endl;
    }
    catch(const std::string& s) {
        std::cout << "抛出字符串:" << s << std::endl;
    }
    catch(const char* s) {
        std::cout << "抛出C字符串:" << s << std::endl;
    }
    catch(...) {
        // 走到这里说明是非多态类型或特殊类型,尝试编译器特定方法
    }
}

针对Boost.Python场景的特殊处理

你是从C++调用Python,大概率抛出的是Boost.Python包装的Python异常,这类异常不会被标准catch分支捕获,直接用Boost.Python的工具处理即可:

#include <boost/python/exception.hpp>
#include <boost/python/handle.hpp>
#include <boost/python/str.hpp>
#include <boost/python/extract.hpp>

try {
    instruction();
}
catch(my_own_namespace::Exception const& e) { /* 处理自定义异常 */ }
catch(std::exception const& e) { /* 处理标准异常 */ }
catch(const boost::python::error_already_set&) {
    // 获取并解析Python异常
    PyObject* exc_type = PyErr_Occurred();
    if(exc_type) {
        // 获取异常类型名称
        boost::python::handle<> handle_type(exc_type);
        boost::python::str type_str(handle_type);
        std::cout << "Python异常类型:" << boost::python::extract<std::string>(type_str)() << std::endl;
        
        // 获取异常详情
        PyObject* exc_value = PyErr_GetArg();
        if(exc_value) {
            boost::python::handle<> handle_value(exc_value);
            boost::python::str value_str(handle_value);
            std::cout << "Python异常信息:" << boost::python::extract<std::string>(value_str)() << std::endl;
        }
        PyErr_Clear(); // 清除Python异常状态
    }
}
catch(std::string const& s) { /* 处理字符串异常 */ }
catch(char const* s) { /* 处理C字符串异常 */ }
catch(...) {
    // 兜底处理,用编译器特定方法获取类型
    const std::type_info* ti = __cxa_current_exception_type();
    if(ti) {
        std::cout << "混淆后的异常类型名:" << ti->name() << std::endl;
        // 可以用c++filt -t 命令解析混淆后的名称,得到可读类型
    }
}

编译器特定的类型识别

GCC/Clang支持__cxa_current_exception_type()函数,能直接获取异常的std::type_info指针,哪怕是非多态类型也能得到类型名(只是名称经过编译器混淆,需要用c++filt工具解析):

#include <typeinfo>

catch(...) {
    const std::type_info* ti = __cxa_current_exception_type();
    if(ti) {
        std::cout << "混淆后的类型名:" << ti->name() << std::endl;
        // 示例:输出如果是NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE,用c++filt解析后是std::__cxx11::basic_string<char>
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 12:25:25