C Python api~字符串分段错误

2024-10-03 13:24:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我是C Python api的新手。 我知道有很多这样的问题,但我并不真正理解它们,因为它们使用不同的模块。 我首先创建了一个echo模块,它将回显特定的数据类型。 (echoINT(100)、echoFLT(100.0)等) 我希望添加字符串支持,尽管这就是问题所在。 我可以用以下代码编写单字节编码的字符:

//C character based echo
short /*<- An attempt to make the module a bit memory friendlier*/ CCHARecho(int CHAR) {
    return printf("%c\n", CHAR);
}

//Character based echo
static PyObject* echoCHAR(PyObject* self, PyObject* args) {
    char CHAR;
    if(!PyArg_ParseTuple(args, "c", &CHAR))
    {
        return NULL;
    }

    return Py_BuildValue("c", CCHARecho(CHAR));
}
//Python syntax: echoCHAR(b'A')
//Then just functions that build the module and all that.

但我发现这段代码有一个分段错误:

//C string based echo
int CSTRecho(char str[10000]) {
    return printf("%s", str);
}

static PyObject* echoStr(PyObject* self, PyObject* args) {
    char str[10000];

    // PyArena_Malloc(str, sizeof(str));
    if (!PyArg_ParseTuple(args, "s", &str))
    {
        return NULL;
    }
    return Py_BuildValue("s", CSTRecho(str));
}

我已经将我的代码插入了gdb,结果证明该程序只尝试写入一个特定的内存位置

(gdb) file python3
Reading symbols from python3...
(No debugging symbols found in python3)
(gdb) run test.py 
Starting program: /usr/bin/python3 test.py
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Program received signal SIGSEGV, Segmentation fault.
0x000000000054a850 in ?? ()
(gdb) 

以下是构建模块的其余代码:

static PyMethodDef echoMethod[] = {
    {"echoINT", echoINT, METH_VARARGS, "echo an integer."}, //"echo" = Python function, echo = points to C function, Take's arguments, Help menu
    {"echoCHAR", echoCHAR, METH_VARARGS, "echo a byte encoded char"},
    {"echoFLT", echoFLT, METH_VARARGS, "echo a floating point number"},
    {"Pecho", echoPOINTER, METH_VARARGS, "echo a memory address of a variable"},
    {"echoSTR", echoStr, METH_VARARGS, "echo a string"},
    {NULL, NULL, 0, NULL} //Terminate
};

static struct PyModuleDef echoModule = {
    PyModuleDef_HEAD_INIT,
    "echoModule", //import echoModule
    "This is really just echo as seen in linux, but without variables.\n",
    -1, //Global
    echoMethod
};

PyMODINIT_FUNC PyInit_echoModule(void) {
    return PyModule_Create(&echoModule);
}

最后,这是setup.py的代码,它与python3 setup.py build一起运行:

from distutils.core import setup, Extension

module = Extension('echoModule', sources = ['echoModule.c'])

setup (name = 'ECHO Package',
        version = '1.0',
        description = 'This is a package for echoModule.',
        ext_modules = [module])

Tags: 代码echoreturnargsstaticnullpython3module