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