Home | History | Annotate | Download | only in Objects
      1 
      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 
      9 typedef void (*destructor1)(void *);
     10 typedef void (*destructor2)(void *, void*);
     11 
     12 static int cobject_deprecation_warning(void)
     13 {
     14     return PyErr_WarnPy3k("CObject type is not supported in 3.x. "
     15         "Please use capsule objects instead.", 1);
     16 }
     17 
     18 
     19 PyObject *
     20 PyCObject_FromVoidPtr(void *cobj, void (*destr)(void *))
     21 {
     22     PyCObject *self;
     23 
     24     if (cobject_deprecation_warning()) {
     25         return NULL;
     26     }
     27 
     28     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;
     36 }
     37 
     38 PyObject *
     39 PyCObject_FromVoidPtrAndDesc(void *cobj, void *desc,
     40                              void (*destr)(void *, void *))
     41 {
     42     PyCObject *self;
     43 
     44     if (cobject_deprecation_warning()) {
     45         return NULL;
     46     }
     47 
     48     if (!desc) {
     49         PyErr_SetString(PyExc_TypeError,
     50                         "PyCObject_FromVoidPtrAndDesc called with null"
     51                         " description");
     52         return NULL;
     53     }
     54     self = PyObject_NEW(PyCObject, &PyCObject_Type);
     55     if (self == NULL)
     56         return NULL;
     57     self->cobject = cobj;
     58     self->destructor = (destructor1)destr;
     59     self->desc = desc;
     60 
     61     return (PyObject *)self;
     62 }
     63 
     64 void *
     65 PyCObject_AsVoidPtr(PyObject *self)
     66 {
     67     if (self) {
     68         if (PyCapsule_CheckExact(self)) {
     69             const char *name = PyCapsule_GetName(self);
     70             return (void *)PyCapsule_GetPointer(self, name);
     71         }
     72         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 
     83 void *
     84 PyCObject_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 
     98 void *
     99 PyCObject_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;
    112 }
    113 
    114 int
    115 PyCObject_SetVoidPtr(PyObject *self, void *cobj)
    116 {
    117     PyCObject* cself = (PyCObject*)self;
    118     if (cself == NULL || !PyCObject_Check(cself) ||
    119 	cself->destructor != NULL) {
    120 	PyErr_SetString(PyExc_TypeError,
    121 			"Invalid call to PyCObject_SetVoidPtr");
    122 	return 0;
    123     }
    124     cself->cobject = cobj;
    125     return 1;
    126 }
    127 
    128 static void
    129 PyCObject_dealloc(PyCObject *self)
    130 {
    131     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);
    138 }
    139 
    140 
    141 PyDoc_STRVAR(PyCObject_Type__doc__,
    142 "C objects to be exported from one extension module to another\n\
    143 \n\
    144 C objects are used for communication between extension modules.  They\n\
    145 provide a way for an extension module to export a C interface to other\n\
    146 extension modules, so that extension modules can use the Python import\n\
    147 mechanism to link to one another.");
    148 
    149 PyTypeObject PyCObject_Type = {
    150     PyVarObject_HEAD_INIT(&PyType_Type, 0)
    151     "PyCObject",		/*tp_name*/
    152     sizeof(PyCObject),		/*tp_basicsize*/
    153     0,				/*tp_itemsize*/
    154     /* methods */
    155     (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*/
    172 };
    173