Re: Functions pointers

"Daniele Pianu" <[email protected]>
Newsgroups gmane.comp.python.pyrex
Message-ID <[email protected]>
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 <[email protected]>:
>
>
> 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 <[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
> >
>
>

_______________________________________________
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.