Merged release21-maint changes.
[python/dscho.git] / Objects / cobject.c
blob872e51591c360c747d1d149a9b5ad68b0bebb0ef
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 typedef struct {
13 PyObject_HEAD
14 void *cobject;
15 void *desc;
16 void (*destructor)(void *);
17 } PyCObject;
19 PyObject *
20 PyCObject_FromVoidPtr(void *cobj, void (*destr)(void *))
22 PyCObject *self;
24 self = PyObject_NEW(PyCObject, &PyCObject_Type);
25 if (self == NULL)
26 return NULL;
27 self->cobject=cobj;
28 self->destructor=destr;
29 self->desc=NULL;
31 return (PyObject *)self;
34 PyObject *
35 PyCObject_FromVoidPtrAndDesc(void *cobj, void *desc,
36 void (*destr)(void *, void *))
38 PyCObject *self;
40 if (!desc) {
41 PyErr_SetString(PyExc_TypeError,
42 "PyCObject_FromVoidPtrAndDesc called with null"
43 " description");
44 return NULL;
46 self = PyObject_NEW(PyCObject, &PyCObject_Type);
47 if (self == NULL)
48 return NULL;
49 self->cobject=cobj;
50 self->destructor=(destructor1)destr;
51 self->desc=desc;
53 return (PyObject *)self;
56 void *
57 PyCObject_AsVoidPtr(PyObject *self)
59 if (self) {
60 if (self->ob_type == &PyCObject_Type)
61 return ((PyCObject *)self)->cobject;
62 PyErr_SetString(PyExc_TypeError,
63 "PyCObject_AsVoidPtr with non-C-object");
65 if (!PyErr_Occurred())
66 PyErr_SetString(PyExc_TypeError,
67 "PyCObject_AsVoidPtr called with null pointer");
68 return NULL;
71 void *
72 PyCObject_GetDesc(PyObject *self)
74 if (self) {
75 if (self->ob_type == &PyCObject_Type)
76 return ((PyCObject *)self)->desc;
77 PyErr_SetString(PyExc_TypeError,
78 "PyCObject_GetDesc with non-C-object");
80 if (!PyErr_Occurred())
81 PyErr_SetString(PyExc_TypeError,
82 "PyCObject_GetDesc called with null pointer");
83 return NULL;
86 void *
87 PyCObject_Import(char *module_name, char *name)
89 PyObject *m, *c;
90 void *r = NULL;
92 if ((m = PyImport_ImportModule(module_name))) {
93 if ((c = PyObject_GetAttrString(m,name))) {
94 r = PyCObject_AsVoidPtr(c);
95 Py_DECREF(c);
97 Py_DECREF(m);
99 return r;
102 static void
103 PyCObject_dealloc(PyCObject *self)
105 if (self->destructor) {
106 if(self->desc)
107 ((destructor2)(self->destructor))(self->cobject, self->desc);
108 else
109 (self->destructor)(self->cobject);
111 PyObject_DEL(self);
115 static char PyCObject_Type__doc__[] =
116 "C objects to be exported from one extension module to another\n\
118 C objects are used for communication between extension modules. They\n\
119 provide a way for an extension module to export a C interface to other\n\
120 extension modules, so that extension modules can use the Python import\n\
121 mechanism to link to one another.";
123 PyTypeObject PyCObject_Type = {
124 PyObject_HEAD_INIT(&PyType_Type)
125 0, /*ob_size*/
126 "PyCObject", /*tp_name*/
127 sizeof(PyCObject), /*tp_basicsize*/
128 0, /*tp_itemsize*/
129 /* methods */
130 (destructor)PyCObject_dealloc, /*tp_dealloc*/
131 (printfunc)0, /*tp_print*/
132 (getattrfunc)0, /*tp_getattr*/
133 (setattrfunc)0, /*tp_setattr*/
134 (cmpfunc)0, /*tp_compare*/
135 (reprfunc)0, /*tp_repr*/
136 0, /*tp_as_number*/
137 0, /*tp_as_sequence*/
138 0, /*tp_as_mapping*/
139 (hashfunc)0, /*tp_hash*/
140 (ternaryfunc)0, /*tp_call*/
141 (reprfunc)0, /*tp_str*/
143 /* Space for future expansion */
144 0L,0L,0L,0L,
145 PyCObject_Type__doc__ /* Documentation string */