[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