[Pyrex] Callback help
Robert Bradshaw
robertwb at math.washington.edu
Wed Apr 21 13:35:49 CEST 2010
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 = <void *>f
>
> my_cheese_data.py_data = <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 = <void
> *>cheese_data.py_callback
> user_data = <void
> *>cheese_data.py_data
> (<object>f)(name, user_data)
>
>
>
>
> _______________________________________________
> Pyrex mailing list
> Pyrex at lists.copyleft.no
> http://lists.copyleft.no/mailman/listinfo/pyrex
More information about the Pyrex
mailing list