blob: 48abb4a645d7ff1a500fe98c13cf7d1a76b1796f [file] [log] [blame]
Guido van Rossum77654a71996-01-12 00:44:03 +00001/***********************************************************
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00002Copyright (c) 2000, BeOpen.com.
3Copyright (c) 1995-2000, Corporation for National Research Initiatives.
4Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
5All rights reserved.
Guido van Rossum77654a71996-01-12 00:44:03 +00006
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00007See the file "Misc/COPYRIGHT" for information on usage and
8redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
Guido van Rossum77654a71996-01-12 00:44:03 +00009******************************************************************/
10
11/* Wrap void* pointers to be passed between C modules */
12
13#include "Python.h"
14
15
16/* Declarations for objects of type PyCObject */
17
Tim Petersdbd9ba62000-07-09 03:09:57 +000018typedef void (*destructor1)(void *);
19typedef void (*destructor2)(void *, void*);
Guido van Rossum1f844491997-10-21 19:48:35 +000020
Guido van Rossum77654a71996-01-12 00:44:03 +000021typedef struct {
Fred Drake3be9a8a2000-07-09 04:14:42 +000022 PyObject_HEAD
23 void *cobject;
24 void *desc;
25 void (*destructor)(void *);
Guido van Rossum77654a71996-01-12 00:44:03 +000026} PyCObject;
27
28PyObject *
Fred Drake3be9a8a2000-07-09 04:14:42 +000029PyCObject_FromVoidPtr(void *cobj, void (*destr)(void *))
Guido van Rossum77654a71996-01-12 00:44:03 +000030{
Fred Drake3be9a8a2000-07-09 04:14:42 +000031 PyCObject *self;
32
33 self = PyObject_NEW(PyCObject, &PyCObject_Type);
34 if (self == NULL)
35 return NULL;
36 self->cobject=cobj;
37 self->destructor=destr;
38 self->desc=NULL;
39
40 return (PyObject *)self;
Guido van Rossum1f844491997-10-21 19:48:35 +000041}
42
43PyObject *
Fred Drake3be9a8a2000-07-09 04:14:42 +000044PyCObject_FromVoidPtrAndDesc(void *cobj, void *desc,
45 void (*destr)(void *, void *))
Guido van Rossum1f844491997-10-21 19:48:35 +000046{
Fred Drake3be9a8a2000-07-09 04:14:42 +000047 PyCObject *self;
Guido van Rossum1f844491997-10-21 19:48:35 +000048
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;
58 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
Guido van Rossum77654a71996-01-12 00:44:03 +0000111static void
Fred Drake3be9a8a2000-07-09 04:14:42 +0000112PyCObject_dealloc(PyCObject *self)
Guido van Rossum77654a71996-01-12 00:44:03 +0000113{
Fred Drake3be9a8a2000-07-09 04:14:42 +0000114 if (self->destructor) {
115 if(self->desc)
116 ((destructor2)(self->destructor))(self->cobject, self->desc);
117 else
118 (self->destructor)(self->cobject);
119 }
120 PyObject_DEL(self);
Guido van Rossum77654a71996-01-12 00:44:03 +0000121}
122
Guido van Rossume0e69621997-01-22 20:48:48 +0000123
Guido van Rossum77654a71996-01-12 00:44:03 +0000124static char PyCObject_Type__doc__[] =
Guido van Rossumcee555b1996-08-01 00:02:33 +0000125"C objects to be exported from one extension module to another\n\
126\n\
127C objects are used for communication between extension modules. They\n\
128provide a way for an extension module to export a C interface to other\n\
129extension modules, so that extension modules can use the Python import\n\
Fred Drake3be9a8a2000-07-09 04:14:42 +0000130mechanism to link to one another.";
Guido van Rossum77654a71996-01-12 00:44:03 +0000131
132PyTypeObject PyCObject_Type = {
Fred Drake3be9a8a2000-07-09 04:14:42 +0000133 PyObject_HEAD_INIT(&PyType_Type)
134 0, /*ob_size*/
135 "PyCObject", /*tp_name*/
136 sizeof(PyCObject), /*tp_basicsize*/
137 0, /*tp_itemsize*/
138 /* methods */
139 (destructor)PyCObject_dealloc, /*tp_dealloc*/
140 (printfunc)0, /*tp_print*/
141 (getattrfunc)0, /*tp_getattr*/
142 (setattrfunc)0, /*tp_setattr*/
143 (cmpfunc)0, /*tp_compare*/
144 (reprfunc)0, /*tp_repr*/
145 0, /*tp_as_number*/
146 0, /*tp_as_sequence*/
147 0, /*tp_as_mapping*/
148 (hashfunc)0, /*tp_hash*/
149 (ternaryfunc)0, /*tp_call*/
150 (reprfunc)0, /*tp_str*/
Guido van Rossum77654a71996-01-12 00:44:03 +0000151
Fred Drake3be9a8a2000-07-09 04:14:42 +0000152 /* Space for future expansion */
153 0L,0L,0L,0L,
154 PyCObject_Type__doc__ /* Documentation string */
Guido van Rossum77654a71996-01-12 00:44:03 +0000155};