如何获得Pythonexception文本

我想在我的C ++应用程序中embeddedpython。 我正在使用Boost库 – 伟大的工具。 但是我有一个问题。

如果python函数抛出一个exception,我想赶上它,并在我的应用程序中打印错误,或得到一些像python脚本中的行号,导致错误的详细信息。

我该怎么做? 我找不到任何函数在Python API或Boost中获取详细的exception信息。

try { module=import("MyModule"); //this line will throw excetion if MyModule contains an error } catch ( error_already_set const & ) { //Here i can said that i have error, but i cant determine what caused an error std::cout << "error!" << std::endl; } 

PyErr_Print()只是打印错误文本到标准错误,并清除错误,所以它不能解决

那么,我发现如何做到这一点。

没有提升(只有错误消息,因为从回溯提取信息的代码是太重,不能发布在这里):

 PyObject *ptype, *pvalue, *ptraceback; PyErr_Fetch(&ptype, &pvalue, &ptraceback); //pvalue contains error message //ptraceback contains stack snapshot and many other information //(see python traceback structure) //Get error message char *pStrErrorMessage = PyString_AsString(pvalue); 

和BOOST版本

 try{ //some code that throws an error }catch(error_already_set &){ PyObject *ptype, *pvalue, *ptraceback; PyErr_Fetch(&ptype, &pvalue, &ptraceback); handle<> hType(ptype); object extype(hType); handle<> hTraceback(ptraceback); object traceback(hTraceback); //Extract error message string strErrorMessage = extract<string>(pvalue); //Extract line number (top entry of call stack) // if you want to extract another levels of call stack // also process traceback.attr("tb_next") recurently long lineno = extract<long> (traceback.attr("tb_lineno")); string filename = extract<string>(traceback.attr("tb_frame").attr("f_code").attr("co_filename")); string funcname = extract<string>(traceback.attr("tb_frame").attr("f_code").attr("co_name")); ... //cleanup here 

这是我迄今为止能够提出的最稳健的方法:

  try { ... } catch (bp::error_already_set) { if (PyErr_Occurred()) { msg = handle_pyerror(); } py_exception = true; bp::handle_exception(); PyErr_Clear(); } if (py_exception) .... // decode a Python exception into a string std::string handle_pyerror() { using namespace boost::python; using namespace boost; PyObject *exc,*val,*tb; object formatted_list, formatted; PyErr_Fetch(&exc,&val,&tb); handle<> hexc(exc),hval(allow_null(val)),htb(allow_null(tb)); object traceback(import("traceback")); if (!tb) { object format_exception_only(traceback.attr("format_exception_only")); formatted_list = format_exception_only(hexc,hval); } else { object format_exception(traceback.attr("format_exception")); formatted_list = format_exception(hexc,hval,htb); } formatted = str("\n").join(formatted_list); return extract<std::string>(formatted); } 

在Python C API中, PyObject_Str返回一个Pythonstring对象的新引用,它以Python对象的stringforms作为parameter passing – 就像Python代码中的str(o)一样。 请注意,exception对象没有“信息如行号” – 这是在追踪对象(您可以使用PyErr_Fetch获取exception对象和追踪对象)。 不知道Boost提供了什么(如果有的话)来使这些特定的C API函数更容易使用,但是最糟糕的情况是,您可以随时使用这些函数,因为它们是在C API本身提供的。