[Pyrex] callback

Duncan Booth duncan at rcp.co.uk
Tue Aug 19 12:10:07 CEST 2003


"Bryan Weingarten" <bryan.weingarten at pobox.com> wrote in
news:002901c36618$8fd44f90$026fa8c0 at belred: 

> -- bound status method does not work
>  i'm not sure what the line
> m.status_callback(self.status)
> should be.  i also tried Myplay.status.  and having status have/have
> not the self parameter. the c code crash in all cases.  are you sure
> it's possible to pass in a bound method?
> 
> 
> class Myplay:
>     def status(self, sec, msec):
>         print sec, msec, self.data
>         return 1
> 
>     def play(self, mp3file):
>         self.data = ('test', 2.0, {1:'one'})
>         m = xxx.Play(mp3file)
>         m.status_callback(self.status)
> 
> if __name__ == '__main__':
>     m = Myplay()
>     m.play(sys.argv[1])
> 

Your problem here is reference counting again. The 
expression 'self.status' creates a new bound method object every time it 
executes.
m.status_callback must increment the reference count on the callback 
parameter otherwise the bound method created by 'self.status' will be 
destroyed as soon as the call the status_callback returns.  The nested 
function version is probably working more by luck than anything else.

So long as you only have one callback per Play object you could just save 
the callback in the Play object, that way it will be kept alive just as 
long as you need it. Something like:

class Play:
    def status_callback(self, callback):
        set_status_callback(self.ctx, _callback_wrapper, <void*>callback)
        self.callback = callback

-- 
Duncan Booth                                             duncan at rcp.co.uk
int month(char *p){return(124864/((p[0]+p[1]-p[2]&0x1f)+1)%12)["\5\x8\3"
"\6\7\xb\1\x9\xa\2\0\4"];} // Who said my code was obscure?




More information about the Pyrex mailing list