用C错误扩展Python:分段错误:Python中的11[MacOS X]

2024-09-27 20:19:35 发布

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

我用C语言编写了一个名为extmodule.C的扩展模块,其代码如下:

#include <Python.h>

//Define a new exception object for our module
static PyObject *extError;

static PyObject* ext_cpu(PyObject* self, PyObject *args)
{
  int pid;
  int sts=0;

  //We expect at least 1 argument to this function
  if(!PyArg_ParseTuple(args, "i", &pid))
  {
    return NULL;
  }


  printf("Hello, from C World! Pid: %i", pid);
  sts=pid;

  return Py_BuildValue("i", sts);
}

static PyMethodDef ext_methods[] = {
  //PythonName, C-FunctionName, argument_presentation, description
  {"cpu", ext_cpu, METH_VARARGS, "Print cpu consumption of a particular process with pid"}
};

PyMODINIT_FUNC
PyInit_ext(void)
{
    PyObject *m;

    m = PyModule_Create(&ext_methods);
    if (m == NULL)
        return NULL;

    extError = PyErr_NewException("spam.error", NULL, NULL);
    Py_INCREF(extError);
    PyModule_AddObject(m, "error", extError);
    return m;
}

之后我创建了一个设置.py在python程序中构建和安装扩展文件,以及设置.py具体如下:

^{pr2}$

现在在命令提示符下,我已经构建了设置.py使用以下命令:

>> python setup.py build

running build running build_ext

building 'ext' extension gcc -Wno-unused-result -Wsign-compare -Wunreachable-code -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I/Users/somdipdey/ anaconda3/include -arch x86_64 -I/Users/somdipdey/anaconda3/include -arch x86_64 -I/usr/local/include -I/Users/somdipdey/anaco nda3/include/python3.6m -c extmodule.c -o build/temp.macosx-10.7-x86_64-3.6/extmodule.o extmodule.c:34:25: warning: incompatible pointer types passing 'PyMethodDef (*)[1]' to parameter of type 'struct PyModuleDef *' [-Wincompatible-pointer-types] m = PyModule_Create(&ext_methods); /Users/somdipdey/anaconda3/include/python3.6m/modsupport.h:158:26: note: expanded from macro 'PyModule_Create' PyModule_Create2(module, PYTHON_API_VERSION) ^~~~~~ /Users/somdipdey/anaconda3/include/python3.6m/modsupport.h:150:60: note: passing argument to parameter here PyAPI_FUNC(PyObject ) PyModule_Create2(struct PyModuleDef, ^ 1 warning generated. gcc -bundle -undefined dynamic_lookup -L/Users/somdipdey/anaconda3/lib -arch x86_64 -L/Users/somdipdey/anaconda3/lib -arch x86 _64 -arch x86_64 build/temp.macosx-10.7-x86_64-3.6/extmodule.o -L/Users/somdipdey/anaconda3/lib -lpthread -o build/lib.macosx- 10.7-x86_64-3.6/ext.cpython-36m-darwin.so

>> python setup.py install

install命令工作正常,但是构建命令给出了1个警告。现在,当我试图在python程序中导入ext并使用函数外部cpu(整数值),程序给出以下错误:

Segmentation Fault: 11

你知道是什么导致了这个问题,以及如何解决它吗?在


Tags: pybuildincludecpupidnullusersext
1条回答
网友
1楼 · 发布于 2024-09-27 20:19:35

警告确切地告诉您出了什么问题:您将一个PyMethodDef (*)[1]传递给PyModule_Create,而它需要一个PyModuleDef *。那些是完全不相关的类型。您得到的segfault类似于aTypeError的C版本。在

You need to create a module definition table,并将该传递给^{}。在


如果您修复了这个问题,那么在退出时可能会有另一个segfault、垃圾数据或神秘的segfault,因为您的方法表在末尾缺少空行。C数组不像Python列表那样知道它们的大小,因此使用它们的代码要么需要在一个单独的变量中传递大小,要么在最后一个槽中使用一些“sentinel”值。PyMethodDef使用后一种解决方案。在


所以:

static PyMethodDef ext_methods[] = {
  //PythonName, C-FunctionName, argument_presentation, description
  {"cpu", ext_cpu, METH_VARARGS, "Print cpu consumption of a particular process with pid"},
  {NULL, NULL, 0, NULL}
};

static struct PyModuleDef ext_module = {
  PyModuleDef_HEAD_INIT,
  "ext",
  "Extension module that does stuff",
  -1,
  ext_methods
};

PyMODINIT_FUNC
PyInit_ext(void)
{
    PyObject *m;

    m = PyModule_Create(&ext_module);
    // the rest is the same as before

通过这些更改,您的模块将在没有警告的情况下生成,并且:

^{pr2}$

……一切正常。在

(嗯,可能有内存泄漏,但这是另一个问题…)

相关问题 更多 >

    热门问题