[Pyrex] Re: callback
Pedro Rodriguez
pedro_rodriguez at club-internet.fr
Mon Aug 18 12:48:07 CEST 2003
On Mon, 18 Aug 2003 03:04:40 +0000, Bryan Weingarten wrote:
> i currently have a callback similar to the cheese demo. but i have a
> problem i hope someone can help me resolve.
>
>
> the following code works correctly... it's basically the "cheese" code:
>
> class Play:
> def status_callback(self, callback):
> set_status_callback(self.ctx, _callback_wrapper, <void*>callback)
>
> cdef int _callback_wrapper(void *callback, long sec, long msec):
> return (<object>callback)(sec, msec)
>
>
> my problem is that the i need user data to be passed into status_callback
> which gets passed back to the python callback. the "cheese" way of doing
> this is to cast the python callback function to a void* and pass it into the
> user data field of the c function. unfortunately, this takes up the one and
> only user data field and doesn't allow for the python user to pass in user
> data. i tried to add the _callback_wrapper as a method of the class so i
> could save the data as instance data, but pyrex complained about that... so
> i'm at a loss now... can someone help me?
>
Instead of just passing the actual python callback, you can pass a python
object that will hold all the data you need.
Example using a tuple object:
class Play:
def status_callback(self, callback, user_data):
data = (callback, user_data)
set_status_callback(self.ctx, _callback_wrapper, <void*>data)
cdef int _callback_wrapper(void *data, long sec, long msec):
callback, user_data = <object>data
return callback(user_data, sec, msec)
But there may be still an issue here. I don't know if the 'data' tuple
provided to the C code (set_status_callback) may be garbage collected.
In that case, it may be required to prevent this by memorizing the last
passed data at global level.
data = None
class Play:
def status_callback(self, callback, user_data):
global data
data = (callback, user_data)
set_status_callback(self.ctx, _callback_wrapper, <void*>data)
cdef int _callback_wrapper(void *data, long sec, long msec):
callback, user_data = <object>data
return callback(user_data, sec, msec)
HTH,
--
Pedro
More information about the Pyrex
mailing list