Alper Akcan : ~/documents/python extending

News

Projects

Documents

Contact

RSS Feed

Donations (SF)

 
Extending Python Example with C
2005-07-22 08:52

$ cat e.c
int fonk (int n)
{
        return n + 1;
}

$ cat w.c
#include <Python.h>

PyObject * wrap_fonk (PyObject *self, PyObject *args)
{
    int n;
    int result;
    if (!PyArg_ParseTuple(args, "i:fonk", &n)) {
        return NULL;
    }
    result = fonk(n);
    return Py_BuildValue("i", result);
}

static PyMethodDef exampleMethods[] = {
    {"fonk", wrap_fonk, 1},
    {NULL, NULL}
};

void initexample (void)
{
    PyObject *m;
    m = Py_InitModule("example", exampleMethods);
}

$ gcc -fpic -c e.c w.c
$ gcc -shared e.o w.o -o example.dll 
/usr/lib/python2.4/config/libpython2.4.dll.a
$ cp example.dll /usr/lib/python2.4/libdyn-load/
$ python

>>> import example
>>> example.fonk(2);
3
>>>
ctrl + d
$ cok $Ik
bash: cok: command not found 


$ cat e.c

typedef struct class_s {
    int i;
} class_t;

int st_new (class_t **st)
{
    *st = (class_t *) malloc(sizeof(class_t));
    (*st)->i = 0;
    return 0;
}

int st_del (class_t *st)
{
    free(st);
    return 0;
}

int st_set_i (class_t *st, int i)
{
    st->i = i;
    return 0;
}

int st_get_i (class_t *st, int *i)
{
    *i = st->i;
    return 0;
}

$ cat w.c

#include <Python.h>
#include <structmember.h>

typedef struct class_s {
    int i;
} class_t;

int st_new (class_t **st);
int st_del (class_t *st);
int st_set_i (class_t *st, int i);
int st_get_i (class_t *st, int *i);

static PyObject * St (PyObject *self, PyObject *args);

typedef struct _class_s {
    PyObject_HEAD
    class_t *st;
} _class_t;

static int pyobject_to_int (PyObject* obj, int* val)
{
    PyObject *intobj;
   
    if (PyNumber_Check(obj)) {
        if (!(intobj = PyNumber_Int(obj))) {
            PyErr_Clear();
            return 0;
        }
        *val = PyInt_AsLong(intobj);
        Py_DECREF(intobj);
        if (PyErr_Occurred()) {
            PyErr_Clear();
            return 0;
        }
        return 1;
    }
    return 0;
}

static void _class_dealloc (PyObject *obj)
{
    _class_t *self = (_class_t *) obj;
    st_del(self->st);
    obj->ob_type->tp_free(obj);
}

static PyObject * _class_new (PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    return St(NULL, args);
}

static int _class_init (_class_t *self, PyObject *args, PyObject *kwds)
{
    static char *kwlist[] = {"i", NULL};
   
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i", kwlist, &self->st->i))
        return -1;

    return 0;
}

static PyObject * _class_get_i (_class_t *self, void *closure)
{
    int i;
    st_get_i(self->st, &i);
    return Py_BuildValue("i", i);
}

static int _class_set_i (_class_t *self, PyObject *value, void *closure)
{
    int i;
    if (value == NULL) {
        PyErr_SetString(PyExc_TypeError, "value == null");
        return -1;
    }
    if (!PyInt_Check(value)) {
         PyErr_SetString(PyExc_TypeError, "value != integer");
         return -1;
    }
    pyobject_to_int(value, &i);
    return st_set_i(self->st, i);
}

static PyObject * get_i (PyObject *self, PyObject *args)
{
    return _class_get_i((_class_t *) self, NULL);
}

static PyObject * set_i (PyObject *self, PyObject *args)
{
    int i;
    if (!PyArg_ParseTuple(args, "i", &i))
        return NULL;
    return Py_BuildValue("i", _class_set_i((_class_t *) self, Py_BuildValue("i", i), NULL));
}

static PyMethodDef _class_methods[] = {
    {"get_i", get_i, 1},
    {"set_i", set_i, 1},
    {NULL, NULL}
};

static PyGetSetDef _class_getseters[] = {
    {"i", (getter) _class_get_i, (setter) _class_set_i, "_class i", NULL},
    {NULL}
};

static PyTypeObject _class_type = {
    PyObject_HEAD_INIT(NULL)
    0,                         /* ob_size */
    "_class",                  /* tp_name */
    sizeof(_class_t),          /* tp_basicsize */
    0,                         /* tp_itemsize */
    _class_dealloc,            /* tp_dealloc */
    0,                         /* tp_print */
    0,                         /* tp_getattr */
    0,                         /* tp_setattr */
    0,                         /* tp_compare */
    0,                         /* tp_repr */
    0,                         /* tp_as_number */
    0,                         /* tp_as_sequence */
    0,                         /* tp_as_mapping */
    0,                         /* tp_hash */
    0,                         /* tp_call */
    0,                         /* tp_str */
    0,                         /* tp_getattro */
    0,                         /* tp_setattro */
    0,                         /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT |
    Py_TPFLAGS_CHECKTYPES |
    Py_TPFLAGS_BASETYPE,       /* tp_flags*/
    "_class object",           /* tp_doc */
    0,                         /* tp_traverse */
    0,                         /* tp_clear */
    0,                         /* tp_richcompare */
    0,                         /* tp_weaklistoffset */
    0,                         /* tp_iter */
    0,                         /* tp_iternext */
    _class_methods,            /* tp_methods */
    0,                         /* tp_members */
    _class_getseters,          /* tp_getset */
    0,                         /* tp_base */
    0,                         /* tp_dict */
    0,                         /* tp_descr_get */
    0,                         /* tp_descr_set */
    0,                         /* tp_dictoffset */
    (initproc) _class_init,    /* tp_init */
    0,                         /* tp_alloc */
    _class_new,                /* tp_new */
};

static PyObject * St (PyObject *self, PyObject *args)
{
    int res;
    _class_t *st = PyObject_New(_class_t, &_class_type);
    res = st_new(&(st->st));
    if (res) {
        PyErr_SetString(PyExc_TypeError, "st_new failed");
        return NULL;
    }
    return (PyObject *) st;
}

static PyMethodDef example_methods[] = {
    {"St", St, 1},
    {NULL, NULL}
};

void initexample (void)
{
    PyObject *m;
    PyObject *dict;
   
    if (PyType_Ready(&_class_type) < 0)
        return;
    _class_type.ob_type = &PyType_Type;
    m = Py_InitModule3("example", example_methods, "Example module.");
    Py_INCREF(&_class_type);
    PyModule_AddObject(m, "_class", (PyObject *) &_class_type);
}

$ cat Makefile
all:
   gcc -fpic -c -I/usr/include/python2.4 e.c w.c
   gcc -shared e.o w.o -o example.dll /usr/lib/python2.4/config/libpython2.4.dll.a
   cp example.dll /usr/lib/python2.4/lib-dynload/

$ make
gcc -fpic -c -I/usr/include/python2.4 e.c w.c
e.c:1: warning: -fpic ignored for target (all code is position independent)
w.c:1: warning: -fpic ignored for target (all code is position independent)
gcc -shared e.o w.o -o example.dll /usr/lib/python2.4/config/libpython2.4.dll.a
cp example.dll /usr/lib/python2.4/lib-dynload/

$ python
Python 2.4.1 (#1, May 27 2005, 18:02:40)
[GCC 3.3.3 (cygwin special)] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import example
>>> s = example.St()
>>> s.i
0
>>> s.i = 9
>>> s.i
9
>>> s.set_i(10);
0
>>> s.i
10
>>> s.get_i();
10
>>> cok $ik ;)
  File "<stdin>", line 1
    cok $ik ;)
        ^
SyntaxError: invalid syntax
>>> del s 



(CL) alper akcan
http://www.valgrind.org   hacker emblem   Valid HTML 4.01!   Viewable With Any Browser   [Valid Rss]   Open Source