blob: b2cae9a40401e1d82eb7ff00aefa62b3437b7196 [file] [log] [blame]
Guido van Rossum77654a71996-01-12 00:44:03 +00001
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
Tim Petersdbd9ba62000-07-09 03:09:57 +00009typedef void (*destructor1)(void *);
10typedef void (*destructor2)(void *, void*);
Guido van Rossum1f844491997-10-21 19:48:35 +000011
Guido van Rossum77654a71996-01-12 00:44:03 +000012typedef struct {
Fred Drake3be9a8a2000-07-09 04:14:42 +000013 PyObject_HEAD
14 void *cobject;
15 void *desc;
16 void (*destructor)(void *);
Guido van Rossum77654a71996-01-12 00:44:03 +000017} PyCObject;
18
19PyObject *
Fred Drake3be9a8a2000-07-09 04:14:42 +000020PyCObject_FromVoidPtr(void *cobj, void (*destr)(void *))
Guido van Rossum77654a71996-01-12 00:44:03 +000021{
Fred Drake3be9a8a2000-07-09 04:14:42 +000022 PyCObject *self;
23
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;
30
31 return (PyObject *)self;
Guido van Rossum1f844491997-10-21 19:48:35 +000032}
33
34PyObject *
Fred Drake3be9a8a2000-07-09 04:14:42 +000035PyCObject_FromVoidPtrAndDesc(void *cobj, void *desc,
36 void (*destr)(void *, void *))
Guido van Rossum1f844491997-10-21 19:48:35 +000037{
Fred Drake3be9a8a2000-07-09 04:14:42 +000038 PyCObject *self;
Guido van Rossum1f844491997-10-21 19:48:35 +000039
Fred Drake3be9a8a2000-07-09 04:14:42 +000040 if (!desc) {
41 PyErr_SetString(PyExc_TypeError,
42 "PyCObject_FromVoidPtrAndDesc called with null"
43 " description");
44 return NULL;
Guido van Rossume0e69621997-01-22 20:48:48 +000045 }
Fred Drake3be9a8a2000-07-09 04:14:42 +000046 self = PyObject_NEW(PyCObject, &PyCObject_Type);
47 if (self == NULL)
48 return NULL;
Jeremy Hylton6d3e0182003-07-11 17:02:39 +000049 self->cobject = cobj;
50 self->destructor = (destructor1)destr;
51 self->desc = desc;
Guido van Rossume0e69621997-01-22 20:48:48 +000052
Fred Drake3be9a8a2000-07-09 04:14:42 +000053 return (PyObject *)self;
54}
55
56void *
57PyCObject_AsVoidPtr(PyObject *self)
58{
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");
64 }
65 if (!PyErr_Occurred())
66 PyErr_SetString(PyExc_TypeError,
67 "PyCObject_AsVoidPtr called with null pointer");
68 return NULL;
69}
70
71void *
72PyCObject_GetDesc(PyObject *self)
73{
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");
79 }
80 if (!PyErr_Occurred())
81 PyErr_SetString(PyExc_TypeError,
82 "PyCObject_GetDesc called with null pointer");
83 return NULL;
84}
85
86void *
87PyCObject_Import(char *module_name, char *name)
88{
89 PyObject *m, *c;
90 void *r = NULL;
91
92 if ((m = PyImport_ImportModule(module_name))) {
93 if ((c = PyObject_GetAttrString(m,name))) {
94 r = PyCObject_AsVoidPtr(c);
95 Py_DECREF(c);
96 }
97 Py_DECREF(m);
98 }
99 return r;
Guido van Rossume0e69621997-01-22 20:48:48 +0000100}
101
Martin v. Löwis01a74b22003-10-19 18:30:01 +0000102int
Neal Norwitzbab05c92006-01-24 06:06:11 +0000103PyCObject_SetVoidPtr(PyObject *self, void *cobj)
Martin v. Löwis01a74b22003-10-19 18:30:01 +0000104{
Neal Norwitzbab05c92006-01-24 06:06:11 +0000105 PyCObject* cself = (PyCObject*)self;
106 if (cself == NULL || !PyCObject_Check(cself) ||
107 cself->destructor != NULL) {
Martin v. Löwis01a74b22003-10-19 18:30:01 +0000108 PyErr_SetString(PyExc_TypeError,
109 "Invalid call to PyCObject_SetVoidPtr");
110 return 0;
111 }
Neal Norwitzbab05c92006-01-24 06:06:11 +0000112 cself->cobject = cobj;
Martin v. Löwis01a74b22003-10-19 18:30:01 +0000113 return 1;
114}
115
Guido van Rossum77654a71996-01-12 00:44:03 +0000116static void
Fred Drake3be9a8a2000-07-09 04:14:42 +0000117PyCObject_dealloc(PyCObject *self)
Guido van Rossum77654a71996-01-12 00:44:03 +0000118{
Fred Drake3be9a8a2000-07-09 04:14:42 +0000119 if (self->destructor) {
120 if(self->desc)
121 ((destructor2)(self->destructor))(self->cobject, self->desc);
122 else
123 (self->destructor)(self->cobject);
124 }
125 PyObject_DEL(self);
Guido van Rossum77654a71996-01-12 00:44:03 +0000126}
127
Guido van Rossume0e69621997-01-22 20:48:48 +0000128
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000129PyDoc_STRVAR(PyCObject_Type__doc__,
Guido van Rossumcee555b1996-08-01 00:02:33 +0000130"C objects to be exported from one extension module to another\n\
131\n\
132C objects are used for communication between extension modules. They\n\
133provide a way for an extension module to export a C interface to other\n\
134extension modules, so that extension modules can use the Python import\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000135mechanism to link to one another.");
Guido van Rossum77654a71996-01-12 00:44:03 +0000136
137PyTypeObject PyCObject_Type = {
Fred Drake3be9a8a2000-07-09 04:14:42 +0000138 PyObject_HEAD_INIT(&PyType_Type)
Georg Brandl347b3002006-03-30 11:57:00 +0000139 0, /*ob_size*/
140 "PyCObject", /*tp_name*/
141 sizeof(PyCObject), /*tp_basicsize*/
142 0, /*tp_itemsize*/
Fred Drake3be9a8a2000-07-09 04:14:42 +0000143 /* methods */
Georg Brandl347b3002006-03-30 11:57:00 +0000144 (destructor)PyCObject_dealloc, /*tp_dealloc*/
145 0, /*tp_print*/
146 0, /*tp_getattr*/
147 0, /*tp_setattr*/
148 0, /*tp_compare*/
149 0, /*tp_repr*/
150 0, /*tp_as_number*/
151 0, /*tp_as_sequence*/
152 0, /*tp_as_mapping*/
153 0, /*tp_hash*/
154 0, /*tp_call*/
155 0, /*tp_str*/
156 0, /*tp_getattro*/
157 0, /*tp_setattro*/
158 0, /*tp_as_buffer*/
159 0, /*tp_flags*/
160 PyCObject_Type__doc__ /*tp_doc*/
Guido van Rossum77654a71996-01-12 00:44:03 +0000161};