Возврат нового PyObject * из C ++ в Python в конечном итоге segfaults - PullRequest
0 голосов
/ 18 января 2019

Я пишу на стороне C ++ и Python библиотеки, которая предоставляет некоторые функциональные возможности в нашем программном обеспечении, написанном на C ++ для сценариев Python. Я собираю некоторые интересующие исходные файлы и файл-обертку, который выглядит как показано ниже, в общую библиотеку и загружаю эту библиотеку, используя ctypes.

extern "C" {
    PyObject *py_get_cxx_set_EXAMPLE(void)
    {
        std::set<long> cset = get_cxx_set_for_python();
        PyGILState_STATE gstate = PyGILState_Ensure();
        PyObject *pyset = PySet_New(NULL);
        for (long c_long: cset)
            PySet_Add(pyset, PyLong_FromLong(c_long));
        PyGILState_Release(gstate);
        return pyset;
    }
}

и на стороне питона:

example_lib.py_get_cxx_set_EXAMPLE.restype = ctypes.py_object
for i in range(0, 1000):
    ret = example_lib.py_get_cxx_set_EXAMPLE()

Я считаю, что первые несколько вызовов будут успешными, но код C ++ будет зависать в середине цикла. После GDB'а я бы нашел конец стека вызовов следующим образом:

#0  0x000055555563244a in PyErr_Occurred ()
#1  0x000055555562a387 in _PyObject_GC_Malloc ()
#2  0x0000555555629ebd in _PyObject_GC_New ()
#3  0x000055555562b23c in PyDict_New ()
#4  0x00007ffff66df9be in python::to_python_object<db::pmbus_diagnostics> (t=...) at python_wrapper/python.hpp:101

Похоже, среда выполнения Python отказывается создавать для меня больше объектов Python (в данном случае, dict) ...!

Что я сделал не так в коде C ++?

EDIT :: Обновлено, см. Ответ

1 Ответ

0 голосов
/ 18 января 2019

ОК, я забыл добавить код, чтобы получить и снять глобальную блокировку интерпретатора для некоторого класса функций. Извините за глупый вопрос.

Верьте в детей Python.

...