[Pyrex] #if

Bryan Weingarten bryan.weingarten at pobox.com
Mon Oct 20 08:46:15 CEST 2003


Bryan Weingarten wrote:

>
> Michael P. Dubner wrote:
>
>> Bryan Weingarten wrote:
>>
>>> i'm sorry, but i need to ask a similar question.  is  _windows in 
>>> the example above defined in a c header file?   here's the line from 
>>> the documentation 
>>
>>
>>
>> Of cause I mean:
>>
>> def map_win32(self, err):
>>   #@if HostOS=="nt"
>>   return _wgpr._builtins._map_win32(err)
>>   #@endif
>>
>> or one can define _windows using any of methods mentioned hereafter.
>>
>>> defined
>>>    Pass any single identifier (except keywords) and by magic you will
>>>    get true if this identifier is defined (including as global
>>>    identifier) or not.
>>>
>>> i don't know what "global identifier" means in this context.  is it 
>>> a python global identifier, a pyrex global identifier a #define 
>>> value in some c header file?   the documentation uses the words 
>>> like  "c-like preprocessor",  "/nearly/ same meaning as in C 
>>> preprocessor",  "Huge difference from C preprocessor".  the one and 
>>> only example uses HostOS= "nt" which is really the python os.name 
>>> variable not a c #defined variable.   i'm just trying to understand.
>>
>>
>>
>> As any preprocessor, discussioned one don't know about identifiers of 
>> host language (Pyrex). C headers parsed by c compiler, while this 
>> preprocessor
>> works _before_ pyrex parser (inside scanner), so it doesn't know 
>> about definitions in headers too.
>> Variables that preprocessor do knows about can be defined explicitly 
>> by #@define directive or passed using -D option for 'pyrexc' or 
>> --pyx-define options for 'setup.py build_ext'. Also there are couple 
>> of implicitly defined constants described on download page:
>> http://www.dubnerm.newmail.ru/soft/PyxPP/
>> Also I should mention that previous version has bug in implementation 
>> of #@define directive, so please download new one if you want to 
>> check it out:
>> http://www.dubnerm.newmail.ru/soft/PyxPP/PyxPP-0.9-2.tar.gz
>>
>
> i really feel bad because i'm having the hardest time trying to make 
> sense of this.   --pyx-define option that you mentioned for setup.py 
> seems like it would fit my situation well, but i just can't find 
> documentation on this.  even google comes up with no hits.  if i do 
> use --pyx-define, then where and how do i use the defined variable in 
> code?  where is an example of this?  i checked the pyrex overview and 
> guide but i didn't find it.
>
> bryan
>
>
> _______________________________________________
> Pyrex mailing list
> Pyrex at lists.copyleft.no
> http://lists.copyleft.no/mailman/listinfo/pyrex
>
>

first of all, i'm sorry if my code is not lined properly.  i'm seem to 
be unable to get it lined up when i email it to myself.  i'm using text, 
not html, but some of the newlines keep being removed after i send it.  
i'm using the mozilla thunderbind email client.  not sure if this is a bug.


this is part of my original code that works correctly but with many 
warnings since i'm using int instead of void * for the ctx

cdef extern from "playif.h":
   int mpgedit_play_init(char *name)
   int  mpgedit_play_frame(int ctx)
   ctypedef int (*status)(int user_data, long sec, long msec) except *
   void mpgedit_play_set_status_callback(int ctx, status callback, void 
*user_data)

def class Play:
   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))



the real signature of mpgedit_play_init return a void * and all the 
functions take a void * for the contexts.  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.  this worked correctly and got rid the 
warnings, but 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.

someone then suggested that i do something like this:

cdef class Play:    cdef void * ctx

    def __init__(self, mp3file):
        self.ctx = mpgedit_play_init(mp3file)
       
    def play(self, callback=None):
        self.callback = callback  #this is line 89
        if callback:
           mpgedit_play_set_status_callback(self.ctx, _callback_wrapper, 
<void*>callback)
        while(mpgedit_play_frame(self.ctx)): 
pass                                                                     

the above compiles but when i play it, i get this error:

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'


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, but i might be wrong about this.

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.  python can call a cdef 
class with a def function...   what is the difference?  i see that a 
cdef class variable can be defined in a cdef class, but i'm not sure i 
want that.

sorry for being a pain.

bryan








More information about the Pyrex mailing list