[Pyrex] Re: how do I "dispatch" calls to different C functions...?

Pedro Rodriguez pedro_rodriguez at club-internet.fr
Sun Jul 27 20:27:28 CEST 2003


On Fri, 25 Jul 2003 19:37:16 +0000, Mike Rovner wrote:

<...snip...>

> Alex Martelli wrote:
>> The problems seems to boil down to: how do I wrap pointers to
>> functions into Python objects in such a way that Pyrex can perform
>> a call through the pointer to function when it gets the object back.
> 
> Haven't you try call PyCObject explicitly?
> 

Going back and forth between C objects and Python object seems to require
special attention.

This is my try on the topic :

# Helper to wrap pointer into python objects
cdef extern from "Python.h": 
    ctypedef void *PyObject
    object PyCObject_FromVoidPtr(void* cobj, void (*destr)(void *))
    void* PyCObject_AsVoidPtr(object)

cdef ptr_wrapper(void *ptr):
    return PyCObject_FromVoidPtr(ptr, NULL)

cdef void *ptr_unwrapper(object obj):
    return PyCObject_AsVoidPtr(obj)


# A sample API
cdef extern from "api.h":
    ctypedef struct t_point

    t_point *point_new(int x, int y)
    void point_del(t_point *p)

    int point_get_x(t_point *p)
    int point_get_y(t_point *p)
    void point_set_x(t_point *p, int x)
    void point_set_y(t_point *p, int y)

ctypedef int (*t_point_getter)(t_point *p)
ctypedef void (*t_point_setter)(t_point *p, int v)


# Definition of "properties"
point_attribs = {
    "x" : (ptr_wrapper(<void *> point_get_x)
                    , ptr_wrapper(<void *> point_set_x))
    , "y" : (ptr_wrapper(<void *> point_get_y)
                    , ptr_wrapper(<void *> point_set_y))
    }

# Wrapper class
cdef class Point:
    cdef t_point *point

    def __new__(self):
        self.point = point_new(0, 0)

    def __dealloc__(self):
        point_del(self.point)

    def __getattr__(self, name):
        cdef t_point_getter getter

        pt = point_attribs[name][0]
        getter = <t_point_getter> ptr_unwrapper(pt)

        return getter(self.point)

    def __setattr__(self, name, value):
        cdef t_point_setter setter

        pt = point_attribs[name][1]
        setter = <t_point_setter> ptr_unwrapper(pt)

        setter(self.point, value)


> Hope that helps,
> Mike

Your remark about the PyCObjet did a lot for me, thanks Mike.

Pedro





More information about the Pyrex mailing list