2010-06-30 162 views
0

我想从我的扩展调用一个c函数,并将问题缩小到这个测试用例。PyArg_ParseTuple导致分段错误

#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

嗯。我觉得你的方法的签名应该是这样的:

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

如果要调用你的test_method作为一个绑定方法(即某些对象实例的方法),self将对象本身。如果test_method是模块函数,则self是在初始化模块时传递给Py_InitModule4()的指针(如果使用的是Py_InitModule(),则为NULL)。问题在于,Python在代码级别上对绑定实例方法和普通函数没有区别,这就是为什么即使您正在实现普通函数,也必须通过self

查看this page了解更多详情。

+0

就是这样,出于好奇,自我指的是什么?该模块? – jtm 2010-06-30 09:36:57

+0

我已经扩展了我的回答来回答这个问题。 – 2010-06-30 10:45:14