【问题标题】:python & c-c++ extended module case segmentfaultpython & c-c++扩展模块案例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,甚至没有解释如何调用该函数,因此我投票关闭

标签: python c++ c


【解决方案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() 运行

【讨论】:

    猜你喜欢
    • 2011-03-31
    • 2010-12-13
    • 1970-01-01
    • 2018-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多