奇怪的进程使用boost.python失败

奇怪的进程使用boost.python失败,python,c++,exception,boost,Python,C++,Exception,Boost,我使用boost.python调用脚本。每个python脚本有3个函数: 初始化-必须在开始时调用 取消初始化-必须在结束时调用以关闭每个对象 进程-必须在初始化和取消初始化之间多次调用 本课程不需要解释: class PyInit { public: PyInit() { Py_Initialize(); } ~PyInit() { Py_Finalize(); } }; 这个类创建PyInit对象实例,然后初始化所有Python对象,并在构造函数中调用“initia

我使用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;
};
由于只有“进程”失败并出现“boost::python::error_ready_set”异常,PyGuard的当前实例将被删除,然后创建一个新实例。以避免可能作为隐藏异常结果的隐藏依赖项

所以,在异常之后,所有python内容都被删除(甚至调用Py_Finalize()),然后再次创建

<4>除此之外,在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(“我的脚本”);
while(true)
{
试一试{
_PyGuard->Process();
}
捕获()
{
bool inited=false;
而(!inited)
{
尝试
{
_pyGuard=nullptr;
_pyGuard=make_shared(“script path.txt”);
inited=true;
}
捕获(字符串和e)
{
}
}
}
} 
_PyGuard=nullptr;
} 
捕获(…)
{
//在这里,它永远不会被抓住。
}
所以,我的问题是,为什么它会掉下来,而且不可追踪

我刚发现它落在第一线:

_pyGuard = make_shared<PyGuard>("script path.txt"); 
\u pyGuard=make_shared(“script path.txt”);

调用,所以我觉得无法捕获的是Python raise异常。为什么?如何预防呢?

问题可能在于您使用了
Py\u Finalize()
。根据Boost1.55文档,您可以。看起来您的程序并不真正需要完成,因此您可以尝试从
~PyInit()
中删除调用

如果出于某种原因确实需要最终确定,您可以查看


至于“不可跟踪的异常”问题,这通常是一次有两个活动异常的结果。当这种情况发生时,C++将简单地中止。这可能是(也可能不是)您的代码所发生的情况

谢谢你,我会尝试测试它!我认为一次可以有两个异常,如果在它完成对第一个异常的解析之前,它引发了第二个异常,这是对的吗?不,从catch块内部抛出一个异常是完全正确的。在这种情况下,第一个例外被视为“已处理”。遇到问题的地方是当一个异常正在传播,并且在catch块之外抛出了一个新异常。