[Pyrex] #if
Greg Ewing
greg at cosc.canterbury.ac.nz
Tue Oct 21 10:44:33 CEST 2003
> when i changed everything to a void * casting everything to an int to
> save in self.ctx then back to a void* for each c function call.
You shouldn't have to do so much casting. It should be possible
to use void * directly wherever needed.
> i wasn't able to break out and get an exception when i controled-c
> in the middle of playing an mp3 like i could with the int. instead,
> at the end of the program i just got a error message about the
> exception being ignored.
In the code below, I've added an except * to the declaration of
mpgedit_play_frame. Not sure if it will solve this problem,
but it may help, because otherwise the while loop is likely
to merrily loop on without ever checking for an exception.
> File "C:\src\cvs\mpgedit\mpgedit\contrib\python\py_mpgedit\mpgedit.pyx",
> line 89, in mpgedit.Play.play
> self.callback = callback
> AttributeError: 'mpgedit.Play' object has no attribute 'callback'
I've also added 'callback' as a C attribute of class Play to
address this.
> also, i don't want ctx to be a class variable. i want each instance to
> have it's own ctx. i'm assuming that ctx in
>
> cdef class Play:
> cdef void * ctx
>
> is a class level variable
It's not, it's an instance variable (or "C attribute" in Pyrex
terminology). Extension types can't have class attributes.
> also, i'm a bit confused about the cdef class. the documentation says
> that python cannot call a cdef function, so i also thought it couldn't
> call a cdef class, but obviously i'm wrong.
Saying "cdef class" is the Pyrex idiom for defining an extension type,
which certainly can be called (i.e. instantiated) from Python. This is
perhaps a bit inconsistent with other uses of "cdef", but I wanted to
keep the number of new reserved words to a minimum.
The following code passes the Pyrex compiler. I don't know whether
it will pass the C compiler, since I don't have the header file.
cdef extern from "playif.h":
void *mpgedit_play_init(char *name)
void *mpgedit_play_frame(void *ctx) except *
ctypedef int (*status)(void *user_data, long sec, long msec) except *
void mpgedit_play_set_status_callback(void *ctx, status callback,
void *user_data)
cdef class Play:
cdef void *ctx
cdef object callback
def __init__(self, mp3file):
self.ctx = mpgedit_play_init(mp3file)
def play(self, callback=None):
self.callback = callback
if callback:
mpgedit_play_set_status_callback(self.ctx,
_callback_wrapper, <void*>callback)
while mpgedit_play_frame(self.ctx):
pass
def status_callback(self, callback):
self.callback = callback
mpgedit_play_set_status_callback(self.ctx, _callback_wrapper,
<void*>callback)
cdef int _callback_wrapper(void *callback, long sec, long msec) except *:
return (<object>callback)((sec, msec))
Greg Ewing, Computer Science Dept, +--------------------------------------+
University of Canterbury, | A citizen of NewZealandCorp, a |
Christchurch, New Zealand | wholly-owned subsidiary of USA Inc. |
greg at cosc.canterbury.ac.nz +--------------------------------------+
More information about the Pyrex
mailing list