| /* Wrap void* pointers to be passed between C modules */ | |
| #include "Python.h" | |
| /* Declarations for objects of type PyCObject */ | |
| typedef void (*destructor1)(void *); | |
| typedef void (*destructor2)(void *, void*); | |
| static int cobject_deprecation_warning(void) | |
| { | |
| return PyErr_WarnPy3k("CObject type is not supported in 3.x. " | |
| "Please use capsule objects instead.", 1); | |
| } | |
| PyObject * | |
| PyCObject_FromVoidPtr(void *cobj, void (*destr)(void *)) | |
| { | |
| PyCObject *self; | |
| if (cobject_deprecation_warning()) { | |
| return NULL; | |
| } | |
| self = PyObject_NEW(PyCObject, &PyCObject_Type); | |
| if (self == NULL) | |
| return NULL; | |
| self->cobject=cobj; | |
| self->destructor=destr; | |
| self->desc=NULL; | |
| return (PyObject *)self; | |
| } | |
| PyObject * | |
| PyCObject_FromVoidPtrAndDesc(void *cobj, void *desc, | |
| void (*destr)(void *, void *)) | |
| { | |
| PyCObject *self; | |
| if (cobject_deprecation_warning()) { | |
| return NULL; | |
| } | |
| 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; | |
| } | |
| void * | |
| PyCObject_AsVoidPtr(PyObject *self) | |
| { | |
| if (self) { | |
| if (PyCapsule_CheckExact(self)) { | |
| const char *name = PyCapsule_GetName(self); | |
| return (void *)PyCapsule_GetPointer(self, name); | |
| } | |
| if (self->ob_type == &PyCObject_Type) | |
| return ((PyCObject *)self)->cobject; | |
| PyErr_SetString(PyExc_TypeError, | |
| "PyCObject_AsVoidPtr with non-C-object"); | |
| } | |
| if (!PyErr_Occurred()) | |
| PyErr_SetString(PyExc_TypeError, | |
| "PyCObject_AsVoidPtr called with null pointer"); | |
| return NULL; | |
| } | |
| void * | |
| PyCObject_GetDesc(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(char *module_name, char *name) | |
| { | |
| PyObject *m, *c; | |
| void *r = NULL; | |
| if ((m = PyImport_ImportModule(module_name))) { | |
| if ((c = PyObject_GetAttrString(m,name))) { | |
| r = PyCObject_AsVoidPtr(c); | |
| Py_DECREF(c); | |
| } | |
| Py_DECREF(m); | |
| } | |
| return r; | |
| } | |
| int | |
| PyCObject_SetVoidPtr(PyObject *self, void *cobj) | |
| { | |
| PyCObject* cself = (PyCObject*)self; | |
| if (cself == NULL || !PyCObject_Check(cself) || | |
| cself->destructor != NULL) { | |
| PyErr_SetString(PyExc_TypeError, | |
| "Invalid call to PyCObject_SetVoidPtr"); | |
| return 0; | |
| } | |
| cself->cobject = cobj; | |
| return 1; | |
| } | |
| static void | |
| PyCObject_dealloc(PyCObject *self) | |
| { | |
| if (self->destructor) { | |
| if(self->desc) | |
| ((destructor2)(self->destructor))(self->cobject, self->desc); | |
| else | |
| (self->destructor)(self->cobject); | |
| } | |
| PyObject_DEL(self); | |
| } | |
| PyDoc_STRVAR(PyCObject_Type__doc__, | |
| "C objects to be exported from one extension module to another\n\ | |
| \n\ | |
| C objects are used for communication between extension modules. They\n\ | |
| provide a way for an extension module to export a C interface to other\n\ | |
| extension modules, so that extension modules can use the Python import\n\ | |
| mechanism to link to one another."); | |
| PyTypeObject PyCObject_Type = { | |
| PyVarObject_HEAD_INIT(&PyType_Type, 0) | |
| "PyCObject", /*tp_name*/ | |
| sizeof(PyCObject), /*tp_basicsize*/ | |
| 0, /*tp_itemsize*/ | |
| /* methods */ | |
| (destructor)PyCObject_dealloc, /*tp_dealloc*/ | |
| 0, /*tp_print*/ | |
| 0, /*tp_getattr*/ | |
| 0, /*tp_setattr*/ | |
| 0, /*tp_compare*/ | |
| 0, /*tp_repr*/ | |
| 0, /*tp_as_number*/ | |
| 0, /*tp_as_sequence*/ | |
| 0, /*tp_as_mapping*/ | |
| 0, /*tp_hash*/ | |
| 0, /*tp_call*/ | |
| 0, /*tp_str*/ | |
| 0, /*tp_getattro*/ | |
| 0, /*tp_setattro*/ | |
| 0, /*tp_as_buffer*/ | |
| 0, /*tp_flags*/ | |
| PyCObject_Type__doc__ /*tp_doc*/ | |
| }; |