Сохранение Python переводчика живым только в течение жизни экземпляра объекта - PullRequest
2 голосов
/ 06 февраля 2020

Я определил класс для использования интерпретатора 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;
}

Как только экземпляр класса уничтожается, я получаю ошибку Access violation reading location, когда доходит до удаления экземпляра _Py_Dealloc(op). Как я могу завершить работу интерпретатора, чтобы успешно удалить ранее созданный экземпляр класса p1 и безопасно создать новый экземпляр класса p2?

1 Ответ

3 голосов
/ 06 февраля 2020

cra sh - это b / c, элемент данных 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;
}

По сравнению с вашим примером , он добавляет #include <pybind11/embed.h> и py::scoped_interpreter m_guard; (где снова следует подчеркнуть, что порядок имеет решающее значение); и это удаляет инициализацию / финализацию интерпретатора.

...