[Pyrex] Re: how do I "dispatch" calls to different C functions...?

Mike Rovner mike at nospam.com
Fri Jul 25 21:37:16 CEST 2003


Alex Martelli wrote:
> I'm trying to wrap the mp3lame library, and it has a *LOT* of
> getter/setter functions which I'd like to wrap into getattr/setattr
> special methods for use from Python.  I've been trying various
> approaches but I keep running into various different errors, so I
> thought I'd ask for guidance.

I had a similar task and a similar problem.
Unfortunately I didn't have time to figure out how to force that
approach to work.
So I went easy way (lazy approach):

> cdef extern from "lame/lame.h":
>
>     ctypedef struct lame_global_flags
>     ctypedef lame_global_flags* lame_t
>
>     lame_t lame_init()
>     int lame_set_num_samples(lame_t, int)
>     int lame_get_num_samples(lame_t)
>
> /* snip: a zillion more lame_set_... and lame_get... declarations */

cdef class Lame:
  cdef lame_t obj

def __set_num_samples(lame,i): return
lame_set_num_samples((<Lame>lame).obj,i) # either
def __get_num_samples(Lame lame): return lame_get_num_samples(lame.obj)  #
or
...zillion dumb converters...
(I can't recall which argument converter I used at the moment :()

> Lamer_int_attribs = {
>  'numSamples': (<long>lame_get_num_samples,
>  <long>lame_set_num_samples), 'inSampleRate':
>  (<long>lame_get_in_samplerate, <long>lame_set_in_samplerate),
> 'numChannels': (<long>lame_get_num_channels,
> <long>lame_set_num_channels), /* snip: a zillion more dict entries in
> exactly the same vein as the above */ }

... {'numSamples': (__get_num_samples, __set_num_samples), ...}

> cdef object Lamer_setter(lame_t flags, char* name, object value):
>     if name not in Lamer_int_attribs: raise AttributeError
>     setter = Lamer_int_attribs[name][1]
>     if (<lame_int_setter>setter)(flags, value):
>         raise lameError(name)

     if  setter(flags, value):
         raise lameError(name)

Now no typecast is needed and I moved wrapper class(es) to a plain .py
module.

> The problems seems to boil down to: how do I wrap pointers to
> functions into Python objects in such a way that Pyrex can perform
> a call through the pointer to function when it gets the object back.

Haven't you try call PyCObject explicitly?

Hope that helps,
Mike







More information about the Pyrex mailing list