diff options
-rw-r--r-- | Include/cobject.h | 15 | ||||
-rw-r--r-- | Objects/cobject.c | 53 |
2 files changed, 66 insertions, 2 deletions
diff --git a/Include/cobject.h b/Include/cobject.h index 672e029..5979074 100644 --- a/Include/cobject.h +++ b/Include/cobject.h @@ -54,14 +54,27 @@ extern DL_IMPORT(PyTypeObject) PyCObject_Type; destroyed. */ - extern PyObject * PyCObject_FromVoidPtr Py_PROTO((void *cobj, void (*destruct)(void*))); + +/* Create a PyCObject from a pointer to a C object, a description object, + and an optional destrutor function. If the third argument is non-null, + then it will be called with the first and second arguments if and when + the PyCObject is destroyed. +*/ +extern PyObject * +PyCObject_FromVoidPtrAndDesc Py_PROTO((void *cobj, void *desc, + void (*destruct)(void*,void*))); + /* Retrieve a pointer to a C object from a PyCObject. */ extern void * PyCObject_AsVoidPtr Py_PROTO((PyObject *)); +/* Retrieve a pointer to a description object from a PyCObject. */ +extern void * +PyCObject_GetDesc Py_PROTO((PyObject *)); + /* Import a pointer to a C object from a module using a PyCObject. */ extern void * PyCObject_Import Py_PROTO((char *module_name, char *cobject_name)); diff --git a/Objects/cobject.c b/Objects/cobject.c index 6b757d5..40e8672 100644 --- a/Objects/cobject.c +++ b/Objects/cobject.c @@ -36,9 +36,13 @@ PERFORMANCE OF THIS SOFTWARE. /* Declarations for objects of type PyCObject */ +typedef void (*destructor1) Py_PROTO((void *)); +typedef void (*destructor2) Py_PROTO((void *, void*)); + typedef struct { PyObject_HEAD void *cobject; + void *desc; void (*destructor) Py_PROTO((void *)); } PyCObject; @@ -54,6 +58,30 @@ PyCObject_FromVoidPtr(cobj, destr) return NULL; self->cobject=cobj; self->destructor=destr; + self->desc=NULL; + return (PyObject *)self; +} + +PyObject * +PyCObject_FromVoidPtrAndDesc(cobj, desc, destr) + void *cobj; + void *desc; + void (*destr) Py_PROTO((void *, void *)); +{ + PyCObject *self; + + if(!desc) { + PyErr_SetString(PyExc_TypeError, + "PyCObject_FromVoidPtrAndDesc called with null description"); + return NULL; + } + + self = PyObject_NEW(PyCObject, &PyCObject_Type); + if (self == NULL) + return NULL; + self->cobject=cobj; + self->destructor=(destructor1)destr; + self->desc=desc; return (PyObject *)self; } @@ -75,6 +103,23 @@ PyCObject_AsVoidPtr(self) } void * +PyCObject_GetDesc(self) + PyObject *self; +{ + if(self) + { + if(self->ob_type == &PyCObject_Type) + return ((PyCObject *)self)->desc; + PyErr_SetString(PyExc_TypeError, + "PyCObject_GetDesc with non-C-object"); + } + if(! PyErr_Occurred()) + PyErr_SetString(PyExc_TypeError, + "PyCObject_GetDesc called with null pointer"); + return NULL; +} + +void * PyCObject_Import(module_name, name) char *module_name; char *name; @@ -99,7 +144,13 @@ static void PyCObject_dealloc(self) PyCObject *self; { - if(self->destructor) (self->destructor)(self->cobject); + if(self->destructor) + { + if(self->desc) + ((destructor2)(self->destructor))(self->cobject, self->desc); + else + (self->destructor)(self->cobject); + } PyMem_DEL(self); } |