Re: problem with callback function
Lenard Lindstrom <len-l <at> telus.net>
2007-12-06 19:07:20 GMT
oyster wrote:
> I am still fighting with IUP - Portable User
> Interface (http://www.tecgraf.puc-rio.br/iup/). Now I have a new
> problem with function pointer(see details below)
>
> Can somebody help me?
>
> And you can download what I have made till now from [
> http://pyguiviactypes.googlepages.com/buggy_iup.zip ] with some
> running examples.
> Thanx
>
> BTW: I disabled recieving digest from the maillist, and only read it
> form www.sourceforge.net, thus can not answer the people who had
> helped me. But I do thank you :)
> (ps1.I prefer to a google maillist, where I can read/post on the webpage
> ps2.if the ctypes manual give the example with C protype, I think it
> could be more firiendly to C newbie like me)
>
It does not help when the library being wrapped does uses advanced C tricks.
>
> [That is the C Part]
> typedef int (*Icallback)(Ihandle*);
>
> //action: name of the action generated when the user types something
> Ihandle* IupText (char* action);
>
> //name: name of an action.
> //func: address of a C function
> Icallback IupSetFunction (const char *name, Icallback func);
>
> int acao_numero (Ihandle *self, int c);
> int main()
> {
> ...
> campo = IupText("acao_numero"); /* creates
> TEXT field */
> IupSetFunction ("acao_numero", (Icallback)acao_numero); /* registers
>
Here the function acao_numero, which takes two arguments, is cast as a
function that only takes a single argument.
> callback */
> ...
> }
> [/That is the C Part]
>
>
>
> [That is the Python part]
> Icallback = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.POINTER(Ihandle))
> _IupText=iup.IupText
> _IupText.argstypes=[ctypes.c_char_p]
> _IupText.restype=ctypes.POINTER(Ihandle)
> def IupText(action):
> return _IupText(action)
>
> def acao_numero (me, c):
> pass
>
> def main():
> ...
> campo = IupText("acao_numero")
> IupSetFunction ("acao_numero", Icallback(acao_numero))
>
At the end of section 14.14.1.17 Callback functions of the Python
Library Reference for Python 2.5 it mentions that a Python reference to
a CFUNCTYPE object or Python will garbage collect it.
> ...
>
> TypeError: acao_numero() takes exactly 2 arguments (1 given)
> [/That is the Python part]
>
>
So try this:
def py_acao_numero (me, c):
pass
acao_numero = ctypes.CFUNCTYPE(ctype.c_int,
ctypes.POINTER(Ihandle),
ctypes.c_int)(py_acao_numero)
def main():
...
campo = IupText("acao_numero")
IupSetFunction ("acao_numero", ctypes.cast(acao_numero, Icallback))
...
Alternatively, do not set the argtypes attribute of IupSetFunction and let ctypes deduce argument types. Then:
IupSetFunction("acao_numero", acao_numero)
When passed as an argument a Python string is by default converted to a
(char *). The callback is a C data object so has an associated C type.
--
--
Lenard Lindstrom
<len-l <at> telus.net>
-------------------------------------------------------------------------
SF.Net email is sponsored by: The Future of Linux Business White Paper
from Novell. From the desktop to the data center, Linux is going
mainstream. Let it simplify your IT future.
http://altfarm.mediaplex.com/ad/ck/8857-50307-18918-4