Stefan Behnel schrieb:
> Hi,
>
> welcome to Cython.
>
> Martin Gysel wrote:
>> I'm quite new to cython and try to bind some c code to python. Now I'm
>> not sure if I understood the cython doc correctly since what I'm trying
>> do do doesn't work :-(
>> It looks like this:
>>
>> cdef class Cobj:
>>     cdef a_c_struct_t *loop
>>
>>     def __init__(self):
>>         self.loop = c_lib_call()
>>         c_lib_call_reg_callback(<c_cb_t>self.callback, NULL)
>>
>>     cdef void callback(self, void *userdata) with gil:
>>        # but here, self.loop seems to be NULL instead of something
>>        # to test this:
>>        # if self.loop == NULL: print "isNull"
>>        doSomething(self.loop)
>>
>> in the callback self.loop is NULL but in the init it wasn't. is it
>> possible to access self and its members in a c callback?
>
> Yes. However, since "callback" is a C function (and not a Python method),
> it cannot remember what instance it belongs to. You will have to pass along
> the pointer to its Python object yourself. This is what the "userdata"
> pointer is there for. It should work to do this:
>
>
>   cdef class Cobj:
>       cdef a_c_struct_t *loop
>
>       def __init__(self):
>           self.loop = c_lib_call()
>           c_lib_call_reg_callback(<c_cb_t>self.callback, <void*>self)
>
>       cdef void callback(self) with gil:
>          if self.loop == NULL: print "isNull"
>          doSomething(self.loop)
thanks Stefan, but now it is a little bit more complex as my callback
expects more than one argument
to register:   
    c_lib_call_reg_callback(mycontext, <c_cb_t>self.callback, <void*>self)

and the callback (as plain c fuction)
    void callback(context *c, void *userdata)

according to your code above, the first argument where the callback gets
called is the first argument of the declared callback (in code above,
cb(userdata) -> callback(self): userdata->self)

so I assume if I have more arguments it works in the same way but then
self would be context instead of userdata (at this point code seems to
get kind of ugly):
    cdef void callback(self, void *userdata)

now I'm asking myself what's the benefit to declare a c callback in the
class rather then outside and and call another class method from there,
like this:
cdef void callback(context *c, void *userdata):
    doWhatHasToBeDone(c)
    anotherOperation(<a_c_struct_t *>(<Cobj>userdata).loop)
    itsDone((<Cobj>userdata).cbDone())

what's the best way to do such things?

/martin


_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev

Reply via email to