Re: Callback help
Robert Bradshaw <[email protected]> Wed, 21 Apr 2010 04:35:49 -0700
| Newsgroups | gmane.comp.python.pyrex |
|---|---|
| Message-ID | <[email protected]> |
On Apr 20, 2010, at 1:20 PM, Dale Cieslak wrote: > Hi all, > > I apologize if this has already been answered or if it's a dumb = > question...I tried looking through the archives and haven't found > anything similar so far. I'm trying to wrap a C API that makes use of > callbacks, and I looked at the cheesefinder callback demo code in the > Pyrex distribution. If I write my code to match the cheesefinder > example, it works fine. However, it appears that the cheesefinder > example passes the Python function pointer as the user_data itself, = > but > what if I want to ALSO pass user data to my Python callback? I = > should > point out that it's been several years since I did any serious C = > coding > (which is why I'm trying to wrap the thing in Python), so I'm hoping > it's just a simple n00b-level solution. I tried various = > permutations > of using PyCObject_AsVoidPtr instead of just casts, but to no avail. > Essentially it compiles fine, but Bus Errors/Seg Faults when it goes = > to call the python callback. If you're casting Python objects to void*, you need to make sure = you're holding onto a reference of them elsewhere (e.g. as an object, = in a list, ...). Otherwise they'll be garbage collected and the void* = you stored will become meaningless (hence the segfaults). > Here's the gist of what I tried. > > Thanks in > advance, > Dale > > cdef extern from "cheesefinder.h": > > ctypedef void (*cheesefunc)(char *name, void *user_data) > void > find_cheeses(cheesefunc user_func, void *user_data) > > ctypedef > struct my_cheese_data: > void *py_callback > void > *py_data > > def find(f, data): > cdef my_cheese_data user_data > my_cheese_data.py_callback =3D <void *>f > > my_cheese_data.py_data =3D <void *>data > > > find_cheeses(super_callback, <void*>&user_data) > > cdef void callback(char *name, void *f): > (<object>f)(name) > > cdef void super_callback(char *name, void *cheese_data): > cdef void *f > cdef void *user_data > > f =3D <void > *>cheese_data.py_callback > user_data =3D <void > *>cheese_data.py_data > (<object>f)(name, user_data) > > > > > _______________________________________________ > Pyrex mailing list > [email protected] > http://lists.copyleft.no/mailman/listinfo/pyrex