move sections
[python/dscho.git] / Objects / cobject.c
blob72123f440a645440d93c6d9ae6c07bf892edb988
2 /* Wrap void* pointers to be passed between C modules */
4 #include "Python.h"
7 /* Declarations for objects of type PyCObject */
9 typedef void (*destructor1)(void *);
10 typedef void (*destructor2)(void *, void*);
12 static int cobject_deprecation_warning(void)
14 return PyErr_WarnEx(PyExc_PendingDeprecationWarning,
15 "The CObject type is marked Pending Deprecation in Python 2.7. "
16 "Please use capsule objects instead.", 1);
20 PyObject *
21 PyCObject_FromVoidPtr(void *cobj, void (*destr)(void *))
23 PyCObject *self;
25 if (cobject_deprecation_warning()) {
26 return NULL;
29 self = PyObject_NEW(PyCObject, &PyCObject_Type);
30 if (self == NULL)
31 return NULL;
32 self->cobject=cobj;
33 self->destructor=destr;
34 self->desc=NULL;
36 return (PyObject *)self;
39 PyObject *
40 PyCObject_FromVoidPtrAndDesc(void *cobj, void *desc,
41 void (*destr)(void *, void *))
43 PyCObject *self;
45 if (cobject_deprecation_warning()) {
46 return NULL;
49 if (!desc) {
50 PyErr_SetString(PyExc_TypeError,
51 "PyCObject_FromVoidPtrAndDesc called with null"
52 " description");
53 return NULL;
55 self = PyObject_NEW(PyCObject, &PyCObject_Type);
56 if (self == NULL)
57 return NULL;
58 self->cobject = cobj;
59 self->destructor = (destructor1)destr;
60 self->desc = desc;
62 return (PyObject *)self;
65 void *
66 PyCObject_AsVoidPtr(PyObject *self)
68 if (self) {
69 if (PyCapsule_CheckExact(self)) {
70 const char *name = PyCapsule_GetName(self);
71 return (void *)PyCapsule_GetPointer(self, name);
73 if (self->ob_type == &PyCObject_Type)
74 return ((PyCObject *)self)->cobject;
75 PyErr_SetString(PyExc_TypeError,
76 "PyCObject_AsVoidPtr with non-C-object");
78 if (!PyErr_Occurred())
79 PyErr_SetString(PyExc_TypeError,
80 "PyCObject_AsVoidPtr called with null pointer");
81 return NULL;
84 void *
85 PyCObject_GetDesc(PyObject *self)
87 if (self) {
88 if (self->ob_type == &PyCObject_Type)
89 return ((PyCObject *)self)->desc;
90 PyErr_SetString(PyExc_TypeError,
91 "PyCObject_GetDesc with non-C-object");
93 if (!PyErr_Occurred())
94 PyErr_SetString(PyExc_TypeError,
95 "PyCObject_GetDesc called with null pointer");
96 return NULL;
99 void *
100 PyCObject_Import(char *module_name, char *name)
102 PyObject *m, *c;
103 void *r = NULL;
105 if ((m = PyImport_ImportModule(module_name))) {
106 if ((c = PyObject_GetAttrString(m,name))) {
107 r = PyCObject_AsVoidPtr(c);
108 Py_DECREF(c);
110 Py_DECREF(m);
112 return r;
116 PyCObject_SetVoidPtr(PyObject *self, void *cobj)
118 PyCObject* cself = (PyCObject*)self;
119 if (cself == NULL || !PyCObject_Check(cself) ||
120 cself->destructor != NULL) {
121 PyErr_SetString(PyExc_TypeError,
122 "Invalid call to PyCObject_SetVoidPtr");
123 return 0;
125 cself->cobject = cobj;
126 return 1;
129 static void
130 PyCObject_dealloc(PyCObject *self)
132 if (self->destructor) {
133 if(self->desc)
134 ((destructor2)(self->destructor))(self->cobject, self->desc);
135 else
136 (self->destructor)(self->cobject);
138 PyObject_DEL(self);
142 PyDoc_STRVAR(PyCObject_Type__doc__,
143 "C objects to be exported from one extension module to another\n\
145 C objects are used for communication between extension modules. They\n\
146 provide a way for an extension module to export a C interface to other\n\
147 extension modules, so that extension modules can use the Python import\n\
148 mechanism to link to one another.");
150 PyTypeObject PyCObject_Type = {
151 PyVarObject_HEAD_INIT(&PyType_Type, 0)
152 "PyCObject", /*tp_name*/
153 sizeof(PyCObject), /*tp_basicsize*/
154 0, /*tp_itemsize*/
155 /* methods */
156 (destructor)PyCObject_dealloc, /*tp_dealloc*/
157 0, /*tp_print*/
158 0, /*tp_getattr*/
159 0, /*tp_setattr*/
160 0, /*tp_compare*/
161 0, /*tp_repr*/
162 0, /*tp_as_number*/
163 0, /*tp_as_sequence*/
164 0, /*tp_as_mapping*/
165 0, /*tp_hash*/
166 0, /*tp_call*/
167 0, /*tp_str*/
168 0, /*tp_getattro*/
169 0, /*tp_setattro*/
170 0, /*tp_as_buffer*/
171 0, /*tp_flags*/
172 PyCObject_Type__doc__ /*tp_doc*/