将新的 PyObject * 从 C++ 返回到 Python 最终会出现段错误
Returning new PyObject * from C++ to Python eventually segfaults
我正在编写一个库的 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;
}
}
python 一侧:
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 对象(在本例中为字典)...!
我在 C++ 代码中做错了什么?
编辑::
已更新,请参阅答案
好的,我忘记添加代码来获取和释放某些 class 函数的全局解释器锁。抱歉这个愚蠢的问题。
对Python孩子有信心。
我正在编写一个库的 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;
}
}
python 一侧:
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 对象(在本例中为字典)...!
我在 C++ 代码中做错了什么?
编辑:: 已更新,请参阅答案
好的,我忘记添加代码来获取和释放某些 class 函数的全局解释器锁。抱歉这个愚蠢的问题。
对Python孩子有信心。