question about handling pointers in C extensions
Harald Kirsch
kirschh at lionbioscience.com
Wed Jul 25 03:47:39 EDT 2001
"Russell E. Owen" <owen at astrono.junkwashington.emu> writes:
> 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);
This makes py_dev_p into a reference you own, therefore ...
> 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);
... neither INCREF nor BuildValue are needed.
> }
In the long run you want to define your own PyObject type in which you
store the DevType *dev_p. The cast to long is a bit of a
hack. Something like
typedef struct {
PyObject_HEAD;
DevType *dev_p;
} DeviceObject;
You then want a related PyTypeObject along the lines of
PyTypeObject deviceTypeObject = {
PyObject_HEAD_INIT(NULL);
0,
"Device",
sizeof(DeviceObject),
0,
/**** more things to come, your book should have an example.
};
Don't forget in your init code to
deviceTypeObject.ob_type = &PyType_Type;
I found it like this in the docs, I think.
Having your own type of objects makes things a bit saver, because you
now can write:
static PyObject*
close (PyObject *obself, PyObject *args)
{
DeviceObject *self;
if( !obself ) {
/* this was called as a module function like
device.close(arg)
where 'device' is the name of your module
*/
if( !PyArg_ParseTuple(args, "O!", &deviceTypeObject, &self) )
return NULL;
} else {
/* this was called like
fin = device.open()
fin.close()
so we are sure already that obself is of the correct type
*/
self = (DeviceObject*)obself;
}
/* Now do it */
whateverCloseFunctionIsNecessary(self->dev_p);
Py_INCREF(Py_None);
return Py_None;
}
Harald Kirsch
--
----------------+------------------------------------------------------
Harald Kirsch | kirschh at lionbioscience.com | "How old is the epsilon?"
LION bioscience | +49 6221 4038 172 | -- Paul Erdös
*** Please do not send me copies of your posts. ***
More information about the Python-list
mailing list