Re: Functions pointers

Robert Bradshaw <[email protected]>
Newsgroups gmane.comp.python.pyrex
Message-ID <[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
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.