[Pyrex] Functions pointers

Daniele Pianu muogoro at gmail.com
Fri Apr 11 12:14:41 CEST 2008


mmm....yes.... I should... -_-' Now it works!!! I paste the all code if
someone has the same problem ;)

------ 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*);


------ 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 returnFoo(int)
  int returnBar(int*)
  char* returnFooBar(char*)
  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>&returnFoo
      self.funcsDict = {}
      self.funcsDict['returnFoo'] = fooPointer
      print self.funcsDict['returnFoo']

  def pyCallFoo(self, foo):
      cdef unsigned long tmp
      tmp = self.funcsDict['returnFoo']
      print tmp
      return callFoo(<int(*)(int)>tmp, foo)



2008/4/11, Robert Bradshaw <robertwb at math.washington.edu>:
>
>
> On Apr 11, 2008, at 2:58 AM, Daniele Pianu wrote:
>
> > 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
> >
>
> Shouldn't you be taking the address of returnFoo here?
>
>
> >      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 :)
> >
> >
> >
> >
> > _______________________________________________
> > Pyrex mailing list
> > Pyrex at lists.copyleft.no
> > http://lists.copyleft.no/mailman/listinfo/pyrex
> >
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.copyleft.no/pipermail/pyrex/attachments/20080411/33c46e27/attachment.html 


More information about the Pyrex mailing list