我使用boost.python调用脚本。每个python脚本有3个函数:
这门课不需要解释:
class PyInit
{
public:
PyInit() { Py_Initialize(); }
~PyInit() { Py_Finalize(); }
};这个类创建PyInit对象实例,然后初始化所有Python,并在构造函数中调用" initialize ()“python函数。并在析构函数处调用"Uninitialize()“。
这个类有函数"Process“多次在类之外调用它。
class PyGuard
{
public:
explicit PyGuard(const char* pypath)
{
try
{
_main_module = boost::python::import("__main__");
_main_namespace = _main_module.attr("__dict__");
boost::python::object ignored = exec_file(pypath, _main_namespace);
_Initialize = _main_namespace["Initialize"];
_Process = _main_namespace["Process"];
_Uninitialize = _main_namespace["Uninitialize"];
_InitRes = _Initialize();
_ProcRes = boost::python::object();
}
catch(boost::python::error_already_set&)
{
string res;
py_utils::err_parse(res);
throw string("Python exception: " + res);
}
catch(std::exception& e)
{
throw string("C++ exception: " + string(e.what()));
}
catch(...)
{
throw string("Unhandled exception!");
}
}
virtual ~PyGuard()
{
_Uninitialize(_InitRes, _ProcRes);
}
void Process()
{
_ProcRes = _Process(_InitRes, _ProcRes);
}
private:
py_utils::PyInit _initPython;
boost::python::object _InitRes;
boost::python::object _ProcRes;
boost::python::object _Process;
boost::python::object _Initialize;
boost::python::object _Uninitialize;
boost::python::object _main_module;
boost::python::object _main_namespace;
};由于只有"Process“与"boost::python::error_already_set”异常一起失败,所以删除PyGuard的当前实例,然后创建新实例。以避免可能导致隐藏异常的隐藏依赖关系。
因此,在异常之后,所有python内容都会被删除(甚至调用Py_Finalize()),然后再次创建。
尽管如此,在4-10个这样的异常之后,整个c++进程都会下降.
跌落,甚至躲避捕手:
try
{
_PyGuard = make_shared<PyGuard>("my script");
while(true)
{
try {
_PyGuard->Process();
}
catch()
{
bool inited = false;
while(!inited)
{
try
{
_pyGuard = nullptr;
_pyGuard = make_shared<PyGuard>("script path.txt");
inited = true;
}
catch(string& e)
{
}
}
}
}
_PyGuard = nullptr;
}
catch(...)
{
//falling, it never being catched here.
}所以,我的问题是,为什么它会掉下来而不能被抓住呢?
我刚发现它在排队:
_pyGuard = make_shared<PyGuard>("script path.txt"); 调用,所以我觉得是Python引发的异常无法捕捉。为什么?以及如何预防呢?
发布于 2014-05-28 07:21:37
您对Py_Finalize()的使用可能是问题所在。根据Boost 1.55文档,您可以使用 with Boost.Python。看起来您的程序并不是真的需要最后确定,所以您可以尝试从~PyInit()中删除调用。
如果您确实因为某些原因需要完成,可以查看Py_NewInterpreter()。
至于您的“不可忽视的异常”问题,这通常是同时具有两个活动异常的结果。当发生这种情况时,C++将简单地中止。这可能(也可能不是)正在发生在您的代码。
https://stackoverflow.com/questions/23889633
复制相似问题