仅在对象实例的生命周期内保持 Python 解释器处于活动状态

AFP*_*AFP 3 c++ python class

我定义了一个使用 python 解释器的类,如下所示:

class pythonInt
{
public:
    pythonInt(const char* fname) {
        py::initialize_interpreter();
        m_Module = py::module::import(fname);
    }
    ~pythonInt() {
        py::finalize_interpreter();
    }
    py::module m_Module;
    // ... other class members and functions that uses m_Module
};

int main()
{
    pythonInt *p1 = new pythonInt("pybind_test1");
    delete(p1); 

    pythonInt *p2 = new pythonInt("pybind_test1");
    delete(p2); 

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

一旦类实例被破坏,Access violation reading location当它达到删除实例时,我就会收到错误_Py_Dealloc(op)。如何完成解释器,以便我可以成功删除以前创建的类实例p1并安全地创建新的类实例p2

Wim*_*sen 5

崩溃是因为数据成员py::module m_Module;在构造函数/析构函数运行之前创建并在运行之后销毁pythonInt,因此在解释器初始化之前和完成之后。

pybind11 满足scoped_interpreter您所寻求的目的,C++ 保证访问块中所有数据成员的构造/销毁顺序。因此,假设您将所有 (Python) 数据保存在一起并且pythonInt没有基类(带有 Python 数据成员),这将是一个选项:

#include <pybind11/pybind11.h>
#include <pybind11/embed.h>

namespace py = pybind11;
class pythonInt
{
public:
    pythonInt(const char* fname) {
        m_Module = py::module::import(fname);
    }
    ~pythonInt() {
    }
    py::scoped_interpreter m_guard;
    py::module m_Module;
    // ... other class members and functions that uses m_Module
};

int main()
{
    pythonInt *p1 = new pythonInt("pybind_test1");
    delete(p1);

    pythonInt *p2 = new pythonInt("pybind_test2");
    delete(p2);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

与您的示例相比,它添加了#include <pybind11/embed.h>py::scoped_interpreter m_guard;(再次强调顺序至关重要);它删除了解释器初始化/终结。

  • `py::error_already_set` 异常的 `what()` 打印实际 Python 异常的 `str()`。那么,它完整地表述了什么?如果没有,请在语句周围执行 `try {} catch(...){}` 并通过 `PyErr_Print()` 打印错误。“pybind_test1”或“pybind_test2”模块中很可能存在 Python 错误。 (2认同)
  • 看起来像“pybind_test1.py”或(在其使用的模块中)存在引用计数问题。错误是因为此谓词“(Py_REFCNT(type) != 0)”对于“PyStructSequence”类型失败。请注意,Python 解释器永远不会卸载共享库,即使此类库所代表的扩展模块已被完全删除,因此任何数据对象都会保留下来,并且显然引用计数没有适当减少。对“pybind_test1.py”进行一些增量调试,删除部分以查找有问题的代码,将允许精确定位有问题的代码(但您可能无法对此做任何事情)。 (2认同)