PyArg_ParseTuple导致段错误

0 投票
1 回答
1910 浏览
提问于 2025-04-16 00:37

我正在尝试从我的扩展中调用一个C语言函数,现在我把问题缩小到了这个测试案例。

#import "Python.h"

...

// Called from python with test_method(0, 0, 'TEST')
static PyObject*
test_method(PyObject *args)
{
    int ok, x, y, size;
    const char *s;

    // this causes Segmentation fault
    //ok = PyArg_ParseTuple(args, "iis#", &x, &y, &s, &size); 

    // also segfaults
    //if(ok) PyErr_SetString(PyExc_SystemError, 'Exception');

    // this does not cause segfault but fills the variables with garbage   
    ok = PyArg_ParseTuple(&args, "iis#", &x, &y, &s, &size);

    // Example: >test_method 0, 37567920, (garbage)
    printf(">test_method %d, %d, %s\n", x, y, s);

    /* Success */
    Py_RETURN_NONE;
}

static PyMethodDef testMethods[] =
{
     {"test_method", test_method, METH_VARARGS,
             "test_method"},
     ...

     {NULL, NULL, 0, NULL}
};

有没有人知道我可能哪里出错了?(使用的是Python 2.6.4版本)。

1 个回答

1

嗯,我觉得你的方法的写法应该是这样的:

static PyObject* test_method(PyObject* self, PyObject* args)

如果你把 test_method 当作一个绑定的方法来调用(也就是说,它是某个对象的一个方法),那么 self 就是这个对象本身。如果 test_method 是一个模块函数,那么 self 就是你在初始化模块时传给 Py_InitModule4() 的指针(如果你用的是 Py_InitModule(),那么就是 NULL)。关键是,Python 在代码层面上并不区分绑定实例方法和普通函数,这就是为什么即使你在实现一个普通函数时也需要传 self 的原因。

想了解更多细节,可以查看这个页面

撰写回答