blob: 355421e635216137e97ccf217e78c2c9be0bb7a1 [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
Larry Hastings5ac006d2010-04-02 11:01:35 +000012static int cobject_deprecation_warning(void)
13{
Jesus Cea33c722b2010-11-04 21:39:52 +000014 return PyErr_WarnPy3k("CObject type is not supported in 3.x. "
Larry Hastings5ac006d2010-04-02 11:01:35 +000015 "Please use capsule objects instead.", 1);
16}
17
18
Guido van Rossum77654a71996-01-12 00:44:03 +000019PyObject *
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
Larry Hastings5ac006d2010-04-02 11:01:35 +000024 if (cobject_deprecation_warning()) {
25 return NULL;
26 }
27
Fred Drake3be9a8a2000-07-09 04:14:42 +000028 self = PyObject_NEW(PyCObject, &PyCObject_Type);
29 if (self == NULL)
30 return NULL;
31 self->cobject=cobj;
32 self->destructor=destr;
33 self->desc=NULL;
34
35 return (PyObject *)self;
Guido van Rossum1f844491997-10-21 19:48:35 +000036}
37
38PyObject *
Fred Drake3be9a8a2000-07-09 04:14:42 +000039PyCObject_FromVoidPtrAndDesc(void *cobj, void *desc,
40 void (*destr)(void *, void *))
Guido van Rossum1f844491997-10-21 19:48:35 +000041{
Fred Drake3be9a8a2000-07-09 04:14:42 +000042 PyCObject *self;
Guido van Rossum1f844491997-10-21 19:48:35 +000043
Larry Hastings5ac006d2010-04-02 11:01:35 +000044 if (cobject_deprecation_warning()) {
45 return NULL;
46 }
47
Fred Drake3be9a8a2000-07-09 04:14:42 +000048 if (!desc) {
49 PyErr_SetString(PyExc_TypeError,
50 "PyCObject_FromVoidPtrAndDesc called with null"
51 " description");
52 return NULL;
Guido van Rossume0e69621997-01-22 20:48:48 +000053 }
Fred Drake3be9a8a2000-07-09 04:14:42 +000054 self = PyObject_NEW(PyCObject, &PyCObject_Type);
55 if (self == NULL)
56 return NULL;
Jeremy Hylton6d3e0182003-07-11 17:02:39 +000057 self->cobject = cobj;
58 self->destructor = (destructor1)destr;
59 self->desc = desc;
Guido van Rossume0e69621997-01-22 20:48:48 +000060
Fred Drake3be9a8a2000-07-09 04:14:42 +000061 return (PyObject *)self;
62}
63
64void *
65PyCObject_AsVoidPtr(PyObject *self)
66{
67 if (self) {
Larry Hastings5ac006d2010-04-02 11:01:35 +000068 if (PyCapsule_CheckExact(self)) {
69 const char *name = PyCapsule_GetName(self);
70 return (void *)PyCapsule_GetPointer(self, name);
71 }
Fred Drake3be9a8a2000-07-09 04:14:42 +000072 if (self->ob_type == &PyCObject_Type)
73 return ((PyCObject *)self)->cobject;
74 PyErr_SetString(PyExc_TypeError,
75 "PyCObject_AsVoidPtr with non-C-object");
76 }
77 if (!PyErr_Occurred())
78 PyErr_SetString(PyExc_TypeError,
79 "PyCObject_AsVoidPtr called with null pointer");
80 return NULL;
81}
82
83void *
84PyCObject_GetDesc(PyObject *self)
85{
86 if (self) {
87 if (self->ob_type == &PyCObject_Type)
88 return ((PyCObject *)self)->desc;
89 PyErr_SetString(PyExc_TypeError,
90 "PyCObject_GetDesc with non-C-object");
91 }
92 if (!PyErr_Occurred())
93 PyErr_SetString(PyExc_TypeError,
94 "PyCObject_GetDesc called with null pointer");
95 return NULL;
96}
97
98void *
99PyCObject_Import(char *module_name, char *name)
100{
101 PyObject *m, *c;
102 void *r = NULL;
103
104 if ((m = PyImport_ImportModule(module_name))) {
105 if ((c = PyObject_GetAttrString(m,name))) {
106 r = PyCObject_AsVoidPtr(c);
107 Py_DECREF(c);
108 }
109 Py_DECREF(m);
110 }
111 return r;
Guido van Rossume0e69621997-01-22 20:48:48 +0000112}
113
Martin v. Löwis01a74b22003-10-19 18:30:01 +0000114int
Neal Norwitzbab05c92006-01-24 06:06:11 +0000115PyCObject_SetVoidPtr(PyObject *self, void *cobj)
Martin v. Löwis01a74b22003-10-19 18:30:01 +0000116{
Neal Norwitzbab05c92006-01-24 06:06:11 +0000117 PyCObject* cself = (PyCObject*)self;
118 if (cself == NULL || !PyCObject_Check(cself) ||
119 cself->destructor != NULL) {
Martin v. Löwis01a74b22003-10-19 18:30:01 +0000120 PyErr_SetString(PyExc_TypeError,
121 "Invalid call to PyCObject_SetVoidPtr");
122 return 0;
123 }
Neal Norwitzbab05c92006-01-24 06:06:11 +0000124 cself->cobject = cobj;
Martin v. Löwis01a74b22003-10-19 18:30:01 +0000125 return 1;
126}
127
Guido van Rossum77654a71996-01-12 00:44:03 +0000128static void
Fred Drake3be9a8a2000-07-09 04:14:42 +0000129PyCObject_dealloc(PyCObject *self)
Guido van Rossum77654a71996-01-12 00:44:03 +0000130{
Fred Drake3be9a8a2000-07-09 04:14:42 +0000131 if (self->destructor) {
132 if(self->desc)
133 ((destructor2)(self->destructor))(self->cobject, self->desc);
134 else
135 (self->destructor)(self->cobject);
136 }
137 PyObject_DEL(self);
Guido van Rossum77654a71996-01-12 00:44:03 +0000138}
139
Guido van Rossume0e69621997-01-22 20:48:48 +0000140
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000141PyDoc_STRVAR(PyCObject_Type__doc__,
Guido van Rossumcee555b1996-08-01 00:02:33 +0000142"C objects to be exported from one extension module to another\n\
143\n\
144C objects are used for communication between extension modules. They\n\
145provide a way for an extension module to export a C interface to other\n\
146extension modules, so that extension modules can use the Python import\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000147mechanism to link to one another.");
Guido van Rossum77654a71996-01-12 00:44:03 +0000148
149PyTypeObject PyCObject_Type = {
Martin v. Löwis68192102007-07-21 06:55:02 +0000150 PyVarObject_HEAD_INIT(&PyType_Type, 0)
Georg Brandl347b3002006-03-30 11:57:00 +0000151 "PyCObject", /*tp_name*/
152 sizeof(PyCObject), /*tp_basicsize*/
153 0, /*tp_itemsize*/
Fred Drake3be9a8a2000-07-09 04:14:42 +0000154 /* methods */
Georg Brandl347b3002006-03-30 11:57:00 +0000155 (destructor)PyCObject_dealloc, /*tp_dealloc*/
156 0, /*tp_print*/
157 0, /*tp_getattr*/
158 0, /*tp_setattr*/
159 0, /*tp_compare*/
160 0, /*tp_repr*/
161 0, /*tp_as_number*/
162 0, /*tp_as_sequence*/
163 0, /*tp_as_mapping*/
164 0, /*tp_hash*/
165 0, /*tp_call*/
166 0, /*tp_str*/
167 0, /*tp_getattro*/
168 0, /*tp_setattro*/
169 0, /*tp_as_buffer*/
170 0, /*tp_flags*/
171 PyCObject_Type__doc__ /*tp_doc*/
Guido van Rossum77654a71996-01-12 00:44:03 +0000172};