PyArg_ParseTuple вызывает ошибку сегментации

Я пытаюсь вызвать функцию 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}
};

Любые идеи, что я могу делать неправильно. (Питон версии 2.6.4).


person jtm    schedule 30.06.2010    source источник


Ответы (1)


Хм. Я думаю, что подпись вашего метода должна быть такой:

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

Если вы вызываете свой test_method как связанный метод (т.е. метод некоторого экземпляра объекта), self будет самим объектом. Если test_method — это функция модуля, self — это указатель, переданный в Py_InitModule4() при инициализации модуля (или NULL, если вы использовали Py_InitModule()). Дело в том, что Python не делает различий между методами связанного экземпляра и обычными функциями на уровне кода, поэтому вам нужно передать self, даже если вы реализуете простую функцию.

Дополнительные сведения см. на этой странице.

person Tamás    schedule 30.06.2010
comment
Это было так, из любопытства, на что ссылается *self ? Модуль? - person jtm; 30.06.2010
comment
Я расширил свой ответ, чтобы ответить на это. - person Tamás; 30.06.2010