question about handling pointers in C extensions

Russell E. Owen owen at astrono.junkwashington.emu
Tue Jul 24 15:14:05 EDT 2001


I would like a bit of help with handling pointers in C extensions. I 
hope this is a simple question.

I want to write a Python interface to a device driver library. One 
starts by opening the device and getting a particular kind of pointer, 
e.g. (simplified):
  DevType *dev_open()

Is the following reasonable, or is there a better way to do this?

static PyObject *open (PyObject *self, PyObject *args)
) {
    PyObject *py_dev_p;
    DevType *dev_p;
    
    /* call the C routine to open the device */
    dev_p = dev_open();
    if (dev_p == NULL) {
        PyErr_SetString(PyExc_RuntimeError, "open failed");
        return NULL;
    }

    /* convert device pointer to a Python Long object */
    py_dev_p = PyLong_FromVoidPtr ((void *) dev_p);
    if (py_dev_p == NULL) {
        return NULL;
    }

    /* increment reference and return the PyLong */
    Py_INCREF (py_dev_p);
    return Py_BuildValue("O", py_dev_p);
}

Also, are there any tricks or gotchas to passing the pointer in to 
device control functions?

I am assuming the inverse functions are the ticket (parse "O" format to 
extract the PyLong, then use PyLong_AsVoidPtr). "O!" sounded interesting 
to get a void* in one step, but what are the "Python type objects" one 
can pass? Anyone have a simple example of a converter function for "O%"?

I assume:
- there is no need to INCREF or DECREF the PyLong pointer (so long as my 
extension only uses it locally, i.e. doesn't store it)
- eventually the user should call a Python interface to dev_close and at 
that time the PyLong should be DECREFed.

Any advice or warnings would be appreciated. I have been reading 
"Extending and Embedding" and "Python/C API", but I still have doubts 
I've got the pointer handling right.

Regards,

-- Russell



More information about the Python-list mailing list