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
cobject_deprecation_warning(void)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 *
PyCObject_FromVoidPtr(void * cobj,void (* destr)(void *))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 *
PyCObject_FromVoidPtrAndDesc(void * cobj,void * desc,void (* destr)(void *,void *))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 *
PyCObject_AsVoidPtr(PyObject * self)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 *
PyCObject_GetDesc(PyObject * self)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 *
PyCObject_Import(char * module_name,char * name)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
PyCObject_SetVoidPtr(PyObject * self,void * cobj)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
PyCObject_dealloc(PyCObject * self)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