views:

29

answers:

1

I'm trying to call a c function from my extension and have narrowed the problem down to this test case.

#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}
};

Any ideas what I might be doing wrong. (Python version 2.6.4).

+1  A: 

Hmmm. I think the signature of your method should be this:

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

If you are invoking your test_method as a bound method (i.e. a method of some object instance), self will be the object itself. If test_method is a module function, self is the pointer passed to Py_InitModule4() when you initialized the module (or NULL if you used Py_InitModule()). The thing is that Python makes no distinctions between bound instance methods and ordinary functions at the code level, that's why you have to pass self even if you are implementing a plain function.

See this page for more details.

Tamás
That was it, out of curiosity, what is *self referring to ? The module ?
leChuck
I've extended my response to answer that.
Tamás