[Pyrex] Functions pointers
Daniele Pianu
muogoro at gmail.com
Fri Apr 11 11:58:07 CEST 2008
I've correct the pyrex code
-------- funcs.pyx --------
cdef extern from "c_funcs.h":
int callFoo(int(*)(int), int)
int callBar(int(*)(int*), int*)
char* callFooBar(char*(*)(char*), char*)
cdef class funcs:
cdef object funcsDict
def __init__(self):
cdef unsigned long fooPointer
fooPointer = <unsigned long>&callFoo
self.funcsDict = {}
self.funcsDict['returnFoo'] = fooPointer
def pyCallFoo(self, foo):
cdef unsigned long tmp
tmp = self.funcsDict['returnFoo']
return callFoo(<int(*)(int)>tmp, foo)
But it gives me a segmentation fault again... :(
2008/4/11, Robert Bradshaw <robertwb at math.washington.edu>:
>
> On Apr 11, 2008, at 2:12 AM, Daniele Pianu wrote:
>
> > I'm trying to wrap a C function that requires a C function pointer as
> > argument. I've wrote a pyrex extension with a dictionary where every key is
> > a C function name, and every entry is a C function pointer, stored as a
> > long. I call the C function from python passing the function name and the
> > necessary data.
> >
> > An example:
> >
> > -------- c_funcs.h ---------
> >
> > int returnFoo(int);
> >
> > int returnBar(int*);
> >
> > char* returnFooBar(char*);
> >
> > int callFoo(int(*)(int), int);
> >
> > int callBar(int(*)(int*), int*);
> >
> > char* callFooBar(char*(*)(char*), char*);
> >
> >
> > ------- c_funcs.c -------
> > #include <c_funcs.h>
> >
> > int returnFoo(int foo){
> > return foo;
> > }
> >
> > int returnBar(int* bar){
> > if (bar)
> > return *bar;
> > }
> >
> > char* returnFooBar(char* fooBar){
> > if (fooBar)
> > return fooBar;
> > }
> >
> > int callFoo(int(*func)(int), int foo){
> > return (*func)(foo);
> > }
> >
> > int callBar(int(*func)(int*), int* bar){
> > return (*func)(bar);
> > }
> >
> > char* callFooBar(char*(*func)(char*), char* FooBar){
> > return (*func)(FooBar);
> > }
> >
> > ------- funcs.pyx ----------
> > cdef extern from "c_funcs.h":
> > int callFoo(int(*)(int), int)
> > int callBar(int(*)(int*), int*)
> > char* callFooBar(char*(*)(char*), char*)
> >
> > cdef class funcs:
> > cdef object funcsDict
> > def __init__(self):
> > cdef unsigned long fooPointer
> > fooPointer = <unsigned long>&callFoo
> > self.funcsDict = {}
> > self.funcsDict['returnFoo'] = fooPointer
> > # Here the python interpreter prints an integer, not a long as
> > expected!!!
> >
>
> Python ints are c longs, which may not actually be the size of pointers on
> all systems.
>
> print self.funcsDict['returnFoo']
> >
> > def pyCallFoo(self, foo):
> > # The call to C function produces a Segmentatio Fault
> > return callFoo(<int(*)(int)>self.funcsDict['returnFoo'], foo)
> >
>
> self.funcsDict['returnFoo'] returns a PyObject* (that points to a Python
> int), and it is the memory location of the object that you are casting to an
> int(*)(int).
>
> In Cython you can write
>
> return callFoo(<int(*)(int)><long>self.funcsDict['returnFoo'], foo)
>
> to force it to unpack the Python long. With in Pyrex you need an extra
> variable
>
> cdef long my_temp_var
> my_temp_var = self.funcsDict['returnFoo']
> return callFoo(<int(*)(int)>my_temp_var, foo)
>
> Just make sure no one messes with your dictionary!
>
>
> >
> > How can I solve the problem? Every advice about alternative
> > implementation is also appreciated :)
> >
>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.copyleft.no/pipermail/pyrex/attachments/20080411/fe34d7ca/attachment.html
More information about the Pyrex
mailing list