|  | 
 | /* 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_WarnEx(PyExc_PendingDeprecationWarning, | 
 |         "The CObject type is marked Pending Deprecation in Python 2.7.  " | 
 |         "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*/ | 
 | }; |