blob: a69215021d2c8e239a7281c48bd502efc5abe50b [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
Georg Brandl5776c162009-05-06 08:47:56 +000012
13static int deprecation_exception(void)
14{
15 return PyErr_WarnEx(PyExc_PendingDeprecationWarning,
16 "The CObject API is deprecated as of Python 3.1. "
17 "Please convert to using the Capsule API.", 1);
18}
19
Guido van Rossum77654a71996-01-12 00:44:03 +000020PyObject *
Fred Drake3be9a8a2000-07-09 04:14:42 +000021PyCObject_FromVoidPtr(void *cobj, void (*destr)(void *))
Guido van Rossum77654a71996-01-12 00:44:03 +000022{
Fred Drake3be9a8a2000-07-09 04:14:42 +000023 PyCObject *self;
24
Georg Brandl5776c162009-05-06 08:47:56 +000025 if (deprecation_exception()) {
26 return NULL;
27 }
28
Fred Drake3be9a8a2000-07-09 04:14:42 +000029 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;
35
36 return (PyObject *)self;
Guido van Rossum1f844491997-10-21 19:48:35 +000037}
38
39PyObject *
Fred Drake3be9a8a2000-07-09 04:14:42 +000040PyCObject_FromVoidPtrAndDesc(void *cobj, void *desc,
41 void (*destr)(void *, void *))
Guido van Rossum1f844491997-10-21 19:48:35 +000042{
Fred Drake3be9a8a2000-07-09 04:14:42 +000043 PyCObject *self;
Guido van Rossum1f844491997-10-21 19:48:35 +000044
Georg Brandl5776c162009-05-06 08:47:56 +000045 if (deprecation_exception()) {
46 return NULL;
47 }
48
Fred Drake3be9a8a2000-07-09 04:14:42 +000049 if (!desc) {
50 PyErr_SetString(PyExc_TypeError,
51 "PyCObject_FromVoidPtrAndDesc called with null"
52 " description");
53 return NULL;
Guido van Rossume0e69621997-01-22 20:48:48 +000054 }
Fred Drake3be9a8a2000-07-09 04:14:42 +000055 self = PyObject_NEW(PyCObject, &PyCObject_Type);
56 if (self == NULL)
57 return NULL;
Jeremy Hylton6d3e0182003-07-11 17:02:39 +000058 self->cobject = cobj;
59 self->destructor = (destructor1)destr;
60 self->desc = desc;
Guido van Rossume0e69621997-01-22 20:48:48 +000061
Fred Drake3be9a8a2000-07-09 04:14:42 +000062 return (PyObject *)self;
63}
64
65void *
66PyCObject_AsVoidPtr(PyObject *self)
67{
68 if (self) {
69 if (self->ob_type == &PyCObject_Type)
70 return ((PyCObject *)self)->cobject;
71 PyErr_SetString(PyExc_TypeError,
72 "PyCObject_AsVoidPtr with non-C-object");
73 }
74 if (!PyErr_Occurred())
75 PyErr_SetString(PyExc_TypeError,
76 "PyCObject_AsVoidPtr called with null pointer");
77 return NULL;
78}
79
80void *
81PyCObject_GetDesc(PyObject *self)
82{
83 if (self) {
84 if (self->ob_type == &PyCObject_Type)
85 return ((PyCObject *)self)->desc;
86 PyErr_SetString(PyExc_TypeError,
87 "PyCObject_GetDesc with non-C-object");
88 }
89 if (!PyErr_Occurred())
90 PyErr_SetString(PyExc_TypeError,
91 "PyCObject_GetDesc called with null pointer");
92 return NULL;
93}
94
95void *
96PyCObject_Import(char *module_name, char *name)
97{
98 PyObject *m, *c;
99 void *r = NULL;
100
101 if ((m = PyImport_ImportModule(module_name))) {
102 if ((c = PyObject_GetAttrString(m,name))) {
103 r = PyCObject_AsVoidPtr(c);
104 Py_DECREF(c);
105 }
106 Py_DECREF(m);
107 }
108 return r;
Guido van Rossume0e69621997-01-22 20:48:48 +0000109}
110
Martin v. Löwis01a74b22003-10-19 18:30:01 +0000111int
Neal Norwitzbab05c92006-01-24 06:06:11 +0000112PyCObject_SetVoidPtr(PyObject *self, void *cobj)
Martin v. Löwis01a74b22003-10-19 18:30:01 +0000113{
Neal Norwitzbab05c92006-01-24 06:06:11 +0000114 PyCObject* cself = (PyCObject*)self;
115 if (cself == NULL || !PyCObject_Check(cself) ||
116 cself->destructor != NULL) {
Martin v. Löwis01a74b22003-10-19 18:30:01 +0000117 PyErr_SetString(PyExc_TypeError,
118 "Invalid call to PyCObject_SetVoidPtr");
119 return 0;
120 }
Neal Norwitzbab05c92006-01-24 06:06:11 +0000121 cself->cobject = cobj;
Martin v. Löwis01a74b22003-10-19 18:30:01 +0000122 return 1;
123}
124
Guido van Rossum77654a71996-01-12 00:44:03 +0000125static void
Fred Drake3be9a8a2000-07-09 04:14:42 +0000126PyCObject_dealloc(PyCObject *self)
Guido van Rossum77654a71996-01-12 00:44:03 +0000127{
Fred Drake3be9a8a2000-07-09 04:14:42 +0000128 if (self->destructor) {
129 if(self->desc)
130 ((destructor2)(self->destructor))(self->cobject, self->desc);
131 else
132 (self->destructor)(self->cobject);
133 }
134 PyObject_DEL(self);
Guido van Rossum77654a71996-01-12 00:44:03 +0000135}
136
Guido van Rossume0e69621997-01-22 20:48:48 +0000137
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000138PyDoc_STRVAR(PyCObject_Type__doc__,
Guido van Rossumcee555b1996-08-01 00:02:33 +0000139"C objects to be exported from one extension module to another\n\
140\n\
141C objects are used for communication between extension modules. They\n\
142provide a way for an extension module to export a C interface to other\n\
143extension modules, so that extension modules can use the Python import\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000144mechanism to link to one another.");
Guido van Rossum77654a71996-01-12 00:44:03 +0000145
146PyTypeObject PyCObject_Type = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000147 PyVarObject_HEAD_INIT(&PyType_Type, 0)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000148 "PyCObject", /*tp_name*/
149 sizeof(PyCObject), /*tp_basicsize*/
150 0, /*tp_itemsize*/
Fred Drake3be9a8a2000-07-09 04:14:42 +0000151 /* methods */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000152 (destructor)PyCObject_dealloc, /*tp_dealloc*/
153 0, /*tp_print*/
154 0, /*tp_getattr*/
155 0, /*tp_setattr*/
Mark Dickinsone94c6792009-02-02 20:36:42 +0000156 0, /*tp_reserved*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000157 0, /*tp_repr*/
158 0, /*tp_as_number*/
159 0, /*tp_as_sequence*/
160 0, /*tp_as_mapping*/
161 0, /*tp_hash*/
162 0, /*tp_call*/
163 0, /*tp_str*/
164 0, /*tp_getattro*/
165 0, /*tp_setattro*/
166 0, /*tp_as_buffer*/
167 0, /*tp_flags*/
168 PyCObject_Type__doc__ /*tp_doc*/
Guido van Rossum77654a71996-01-12 00:44:03 +0000169};