1 2 /* Wrap void* pointers to be passed between C modules */ 3 4 #include "Python.h" 5 6 7 /* Declarations for objects of type PyCObject */ 8 9 typedef void (*destructor1)(void *); 10 typedef void (*destructor2)(void *, void*); 11 12 static int cobject_deprecation_warning(void) 13 { 14 return PyErr_WarnPy3k("CObject type is not supported in 3.x. " 15 "Please use capsule objects instead.", 1); 16 } 17 18 19 PyObject * 20 PyCObject_FromVoidPtr(void *cobj, void (*destr)(void *)) 21 { 22 PyCObject *self; 23 24 if (cobject_deprecation_warning()) { 25 return NULL; 26 } 27 28 self = PyObject_NEW(PyCObject, &PyCObject_Type); 29 if (self == NULL) 30 return NULL; 31 self->cobject=cobj; 32 self->destructor=destr; 33 self->desc=NULL; 34 35 return (PyObject *)self; 36 } 37 38 PyObject * 39 PyCObject_FromVoidPtrAndDesc(void *cobj, void *desc, 40 void (*destr)(void *, void *)) 41 { 42 PyCObject *self; 43 44 if (cobject_deprecation_warning()) { 45 return NULL; 46 } 47 48 if (!desc) { 49 PyErr_SetString(PyExc_TypeError, 50 "PyCObject_FromVoidPtrAndDesc called with null" 51 " description"); 52 return NULL; 53 } 54 self = PyObject_NEW(PyCObject, &PyCObject_Type); 55 if (self == NULL) 56 return NULL; 57 self->cobject = cobj; 58 self->destructor = (destructor1)destr; 59 self->desc = desc; 60 61 return (PyObject *)self; 62 } 63 64 void * 65 PyCObject_AsVoidPtr(PyObject *self) 66 { 67 if (self) { 68 if (PyCapsule_CheckExact(self)) { 69 const char *name = PyCapsule_GetName(self); 70 return (void *)PyCapsule_GetPointer(self, name); 71 } 72 if (self->ob_type == &PyCObject_Type) 73 return ((PyCObject *)self)->cobject; 74 PyErr_SetString(PyExc_TypeError, 75 "PyCObject_AsVoidPtr with non-C-object"); 76 } 77 if (!PyErr_Occurred()) 78 PyErr_SetString(PyExc_TypeError, 79 "PyCObject_AsVoidPtr called with null pointer"); 80 return NULL; 81 } 82 83 void * 84 PyCObject_GetDesc(PyObject *self) 85 { 86 if (self) { 87 if (self->ob_type == &PyCObject_Type) 88 return ((PyCObject *)self)->desc; 89 PyErr_SetString(PyExc_TypeError, 90 "PyCObject_GetDesc with non-C-object"); 91 } 92 if (!PyErr_Occurred()) 93 PyErr_SetString(PyExc_TypeError, 94 "PyCObject_GetDesc called with null pointer"); 95 return NULL; 96 } 97 98 void * 99 PyCObject_Import(char *module_name, char *name) 100 { 101 PyObject *m, *c; 102 void *r = NULL; 103 104 if ((m = PyImport_ImportModule(module_name))) { 105 if ((c = PyObject_GetAttrString(m,name))) { 106 r = PyCObject_AsVoidPtr(c); 107 Py_DECREF(c); 108 } 109 Py_DECREF(m); 110 } 111 return r; 112 } 113 114 int 115 PyCObject_SetVoidPtr(PyObject *self, void *cobj) 116 { 117 PyCObject* cself = (PyCObject*)self; 118 if (cself == NULL || !PyCObject_Check(cself) || 119 cself->destructor != NULL) { 120 PyErr_SetString(PyExc_TypeError, 121 "Invalid call to PyCObject_SetVoidPtr"); 122 return 0; 123 } 124 cself->cobject = cobj; 125 return 1; 126 } 127 128 static void 129 PyCObject_dealloc(PyCObject *self) 130 { 131 if (self->destructor) { 132 if(self->desc) 133 ((destructor2)(self->destructor))(self->cobject, self->desc); 134 else 135 (self->destructor)(self->cobject); 136 } 137 PyObject_DEL(self); 138 } 139 140 141 PyDoc_STRVAR(PyCObject_Type__doc__, 142 "C objects to be exported from one extension module to another\n\ 143 \n\ 144 C objects are used for communication between extension modules. They\n\ 145 provide a way for an extension module to export a C interface to other\n\ 146 extension modules, so that extension modules can use the Python import\n\ 147 mechanism to link to one another."); 148 149 PyTypeObject PyCObject_Type = { 150 PyVarObject_HEAD_INIT(&PyType_Type, 0) 151 "PyCObject", /*tp_name*/ 152 sizeof(PyCObject), /*tp_basicsize*/ 153 0, /*tp_itemsize*/ 154 /* methods */ 155 (destructor)PyCObject_dealloc, /*tp_dealloc*/ 156 0, /*tp_print*/ 157 0, /*tp_getattr*/ 158 0, /*tp_setattr*/ 159 0, /*tp_compare*/ 160 0, /*tp_repr*/ 161 0, /*tp_as_number*/ 162 0, /*tp_as_sequence*/ 163 0, /*tp_as_mapping*/ 164 0, /*tp_hash*/ 165 0, /*tp_call*/ 166 0, /*tp_str*/ 167 0, /*tp_getattro*/ 168 0, /*tp_setattro*/ 169 0, /*tp_as_buffer*/ 170 0, /*tp_flags*/ 171 PyCObject_Type__doc__ /*tp_doc*/ 172 }; 173