python & c-c++扩展模块案例segmentfault
Posted
技术标签:
【中文标题】python & c-c++扩展模块案例segmentfault【英文标题】:python & c-c++ extended module case segmentfault 【发布时间】:2020-01-07 03:03:36 【问题描述】:c++代码
extern "C" PyObject * test()
PyObject *oplist = PyList_New(10000);
for(uint32_t j = 0; j < 10000; j++)
PyObject* pTuple = PyTuple_New(3);
assert(PyTuple_Check(pTuple));
assert(PyTuple_Size(pTuple) == 3);
PyTuple_SetItem(pTuple, 0, Py_BuildValue("s", "b"));
PyTuple_SetItem(pTuple, 1, Py_BuildValue("i", 1));
PyTuple_SetItem(pTuple, 2, Py_BuildValue("s", "a"));
PyList_SetItem(oplist, j, pTuple);
return oplist;
python 代码
LID = ctypes.CDLL('%s/token2map_lib.so' % '.')
LID.test.restype = py_object
LID.test()
构建命令
g++ -fPIC token2map.cpp -I/usr/local/app/service/virtualenvs/NLP/include/python2.7 -shared -o token2map_lib.so
我只是展示了一部分代码,见谅,总代码太长了
问题: 在 c++ 代码中,这个函数返回 res_list 很小,一切正常。永远,结果集超过 215(j = 215) 个 case segmentfalut。我找不到问题,希望现在的朋友能给我一些建议,我将非常感激。
我有办法解决这个问题
extern "C" PyObject * test()
PyGILState_STATE gstate = PyGILState_Ensure();
PyObject *oplist = PyTuple_New(10000);
for(int32_t j = 0; j < 10000; j++)
PyObject * pTuple = PyTuple_New(3);
assert(PyTuple_Check(pTuple));
assert(PyTuple_Size(pTuple) == 3);
PyTuple_SetItem(pTuple, 0, Py_BuildValue("s", "b"));
PyTuple_SetItem(pTuple, 1, Py_BuildValue("i", 1));
PyTuple_SetItem(pTuple, 2, Py_BuildValue("s", "a"));
PyTuple_SetItem(oplist, j, pTuple);
PyGILState_Release(gstate);
return oplist;
但是有没有其他方法可以解决这个问题?我不认为获得 GIL locak 是一种好方法
【问题讨论】:
您永远不会检查这些函数中任何的返回值。如文档所述,您必须始终检查每个 Python API 函数的每个返回值是否返回值。 断言不是进行检查的正确方法。 无论如何,这个问题似乎没有minimal reproducible example,甚至没有解释如何调用该函数,因此我投票关闭 【参考方案1】:我无法解释为什么您的代码会出现段错误。我确实觉得有趣的是,您能够使用不带参数的函数构建您的扩展。但是,我可以提供可以构建和工作的代码:
#define Py_SSIZE_T_CLEAN
#include <Python.h>
#include <inttypes.h>
#ifdef __cplusplus
extern "C"
#endif
static PyObject *test(PyObject *self, PyObject *ignorethis)
PyObject *oplist = PyList_New(10000);
for(uint32_t j = 0; j < 10000; ++j)
PyObject *pTuple = PyTuple_New(3);
PyTuple_SetItem(pTuple, 0, Py_BuildValue("s", "b"));
PyTuple_SetItem(pTuple, 1, Py_BuildValue("i", 1));
PyTuple_SetItem(pTuple, 2, Py_BuildValue("s", "a"));
PyList_SetItem(oplist, j, pTuple);
return oplist;
static PyMethodDef methods[] =
"test", test, METH_NOARGS, "function given by so"
;
static PyModuleDef foobar =
PyModuleDef_HEAD_INIT,
"foobar",
"so question module",
-1,
methods
;
PyMODINIT_FUNC PyInit_foobar(void)
PyObject *module;
module = PyModule_Create(&foobar);
return module;
#ifdef __cplusplus
#endif
您可以使用import foobar
加载此模块,然后使用foobar.test()
运行
【讨论】:
以上是关于python & c-c++扩展模块案例segmentfault的主要内容,如果未能解决你的问题,请参考以下文章