将列表作为参数从 python 传递给 C++:第二次 运行 时出现分段错误(核心已转储)

pass a list as an argument from python to C++: Segmentation fault (core dumped) when running the second time

我正在使用 C++ 编写自定义 python 模块嵌入。

test.py

import my_module
column_names = ['ukey', 'OrderRef', 'orderSize']
print(my_module.my_func(column_names))

my_module.cpp (部分)

static PyObject * my_func(PyObject *self, PyObject *args)
{
    Py_Initialize();
    if(!Py_IsInitialized()) { std::cout<<"PythonInit failed!"<<std::endl; }

    PyObject *_list = nullptr;
    int len;
    std::vector<std::string> c_colArray;

    if (!PyArg_ParseTuple(args, "O", &_list)) {
        PyErr_SetString(PyExc_TypeError, "parameter type error.");
        return NULL;
    }
    len = PyList_Size(_list);

    PyObject * _item = nullptr;
    const char * _line;        /* pointer to the line as a string */
    for (int i = 0; i < len; i++) {
        _item = PyList_GetItem(_list, i); 
        _line = PyUnicode_AsUTF8(_item);
        std::string _elem = _line;
        c_colArray.push_back(_elem);
    }

    Py_DECREF(_list);
    return Py_BuildValue("sss", c_colArray[0].c_str(), c_colArray[1].c_str(), c_colArray[2].c_str());
}

输出

('ukey', 'OrderRef', 'orderSize')

第一次调用my_func时代码运行良好,但再次调用时崩溃并出现Segmentation fault (core dumped)

不需要 C++ 代码中输入列表的

Py_DECREF。 PyArg_ParseTuple 只是做解析,就像一些类型转换,而不是创建一个新的 Python 对象。

Py_DECREF(_list);

之后python中的column_names会变成[]。然后再次调用 my_func ,输入列表在第二次调用时是一个空列表。所以 c_colArray 不包含任何内容,最后一个 c_colArray[0] 将导致分段错误。

简单的解决方案是删除 Py_DECREF(_list);

您可以像这样在 python 代码中轻松输出 column_names

import my_module
column_names = ['ukey', 'OrderRef', 'orderSize']
print(my_module.my_func(column_names))
print(column_names)
print(my_module.my_func(column_names))