blob: c437491c27c26bc57aa60557b43abf0180bc8a84 [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 +000012PyObject *
Fred Drake3be9a8a2000-07-09 04:14:42 +000013PyCObject_FromVoidPtr(void *cobj, void (*destr)(void *))
Guido van Rossum77654a71996-01-12 00:44:03 +000014{
Fred Drake3be9a8a2000-07-09 04:14:42 +000015 PyCObject *self;
16
17 self = PyObject_NEW(PyCObject, &PyCObject_Type);
18 if (self == NULL)
19 return NULL;
20 self->cobject=cobj;
21 self->destructor=destr;
22 self->desc=NULL;
23
24 return (PyObject *)self;
Guido van Rossum1f844491997-10-21 19:48:35 +000025}
26
27PyObject *
Fred Drake3be9a8a2000-07-09 04:14:42 +000028PyCObject_FromVoidPtrAndDesc(void *cobj, void *desc,
29 void (*destr)(void *, void *))
Guido van Rossum1f844491997-10-21 19:48:35 +000030{
Fred Drake3be9a8a2000-07-09 04:14:42 +000031 PyCObject *self;
Guido van Rossum1f844491997-10-21 19:48:35 +000032
Fred Drake3be9a8a2000-07-09 04:14:42 +000033 if (!desc) {
34 PyErr_SetString(PyExc_TypeError,
35 "PyCObject_FromVoidPtrAndDesc called with null"
36 " description");
37 return NULL;
Guido van Rossume0e69621997-01-22 20:48:48 +000038 }
Fred Drake3be9a8a2000-07-09 04:14:42 +000039 self = PyObject_NEW(PyCObject, &PyCObject_Type);
40 if (self == NULL)
41 return NULL;
Jeremy Hylton6d3e0182003-07-11 17:02:39 +000042 self->cobject = cobj;
43 self->destructor = (destructor1)destr;
44 self->desc = desc;
Guido van Rossume0e69621997-01-22 20:48:48 +000045
Fred Drake3be9a8a2000-07-09 04:14:42 +000046 return (PyObject *)self;
47}
48
49void *
50PyCObject_AsVoidPtr(PyObject *self)
51{
52 if (self) {
53 if (self->ob_type == &PyCObject_Type)
54 return ((PyCObject *)self)->cobject;
55 PyErr_SetString(PyExc_TypeError,
56 "PyCObject_AsVoidPtr with non-C-object");
57 }
58 if (!PyErr_Occurred())
59 PyErr_SetString(PyExc_TypeError,
60 "PyCObject_AsVoidPtr called with null pointer");
61 return NULL;
62}
63
64void *
65PyCObject_GetDesc(PyObject *self)
66{
67 if (self) {
68 if (self->ob_type == &PyCObject_Type)
69 return ((PyCObject *)self)->desc;
70 PyErr_SetString(PyExc_TypeError,
71 "PyCObject_GetDesc with non-C-object");
72 }
73 if (!PyErr_Occurred())
74 PyErr_SetString(PyExc_TypeError,
75 "PyCObject_GetDesc called with null pointer");
76 return NULL;
77}
78
79void *
80PyCObject_Import(char *module_name, char *name)
81{
82 PyObject *m, *c;
83 void *r = NULL;
84
85 if ((m = PyImport_ImportModule(module_name))) {
86 if ((c = PyObject_GetAttrString(m,name))) {
87 r = PyCObject_AsVoidPtr(c);
88 Py_DECREF(c);
89 }
90 Py_DECREF(m);
91 }
92 return r;
Guido van Rossume0e69621997-01-22 20:48:48 +000093}
94
Martin v. Löwis01a74b22003-10-19 18:30:01 +000095int
Neal Norwitzbab05c92006-01-24 06:06:11 +000096PyCObject_SetVoidPtr(PyObject *self, void *cobj)
Martin v. Löwis01a74b22003-10-19 18:30:01 +000097{
Neal Norwitzbab05c92006-01-24 06:06:11 +000098 PyCObject* cself = (PyCObject*)self;
99 if (cself == NULL || !PyCObject_Check(cself) ||
100 cself->destructor != NULL) {
Martin v. Löwis01a74b22003-10-19 18:30:01 +0000101 PyErr_SetString(PyExc_TypeError,
102 "Invalid call to PyCObject_SetVoidPtr");
103 return 0;
104 }
Neal Norwitzbab05c92006-01-24 06:06:11 +0000105 cself->cobject = cobj;
Martin v. Löwis01a74b22003-10-19 18:30:01 +0000106 return 1;
107}
108
Guido van Rossum77654a71996-01-12 00:44:03 +0000109static void
Fred Drake3be9a8a2000-07-09 04:14:42 +0000110PyCObject_dealloc(PyCObject *self)
Guido van Rossum77654a71996-01-12 00:44:03 +0000111{
Fred Drake3be9a8a2000-07-09 04:14:42 +0000112 if (self->destructor) {
113 if(self->desc)
114 ((destructor2)(self->destructor))(self->cobject, self->desc);
115 else
116 (self->destructor)(self->cobject);
117 }
118 PyObject_DEL(self);
Guido van Rossum77654a71996-01-12 00:44:03 +0000119}
120
Guido van Rossume0e69621997-01-22 20:48:48 +0000121
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000122PyDoc_STRVAR(PyCObject_Type__doc__,
Guido van Rossumcee555b1996-08-01 00:02:33 +0000123"C objects to be exported from one extension module to another\n\
124\n\
125C objects are used for communication between extension modules. They\n\
126provide a way for an extension module to export a C interface to other\n\
127extension modules, so that extension modules can use the Python import\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000128mechanism to link to one another.");
Guido van Rossum77654a71996-01-12 00:44:03 +0000129
130PyTypeObject PyCObject_Type = {
Martin v. Löwis68192102007-07-21 06:55:02 +0000131 PyVarObject_HEAD_INIT(&PyType_Type, 0)
Georg Brandl347b3002006-03-30 11:57:00 +0000132 "PyCObject", /*tp_name*/
133 sizeof(PyCObject), /*tp_basicsize*/
134 0, /*tp_itemsize*/
Fred Drake3be9a8a2000-07-09 04:14:42 +0000135 /* methods */
Georg Brandl347b3002006-03-30 11:57:00 +0000136 (destructor)PyCObject_dealloc, /*tp_dealloc*/
137 0, /*tp_print*/
138 0, /*tp_getattr*/
139 0, /*tp_setattr*/
140 0, /*tp_compare*/
141 0, /*tp_repr*/
142 0, /*tp_as_number*/
143 0, /*tp_as_sequence*/
144 0, /*tp_as_mapping*/
145 0, /*tp_hash*/
146 0, /*tp_call*/
147 0, /*tp_str*/
148 0, /*tp_getattro*/
149 0, /*tp_setattro*/
150 0, /*tp_as_buffer*/
151 0, /*tp_flags*/
152 PyCObject_Type__doc__ /*tp_doc*/
Guido van Rossum77654a71996-01-12 00:44:03 +0000153};