Re: Functions pointers

"Daniele Pianu" <[email protected]>
Newsgroups gmane.comp.python.pyrex
Message-ID <[email protected]>
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 <[email protected]>:
>
> 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
[email protected]
http://lists.copyleft.no/mailman/listinfo/pyrex
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.