[cffi-devel] Re: unnamed callback (closures?)

Jan Rychter jan at rychter.com
Wed Feb 1 11:03:10 UTC 2006


> >>>>> On Wed, 01 Feb 2006 09:46:27 +0100, Jan Rychter <jan at rychter.com> said:
> >>>>> "Luís" == Luís Oliveira <luismbo at gmail.com>:
> >  Luís> "Hoehle, Joerg-Cyril" <Joerg-Cyril.Hoehle at t-systems.com> writes:
> >  >> In CLISP, every closure can be turned into a callback, and this is
> >  >> valuable since it allows to retrieve context information out of the
> >  >> closure.  Is cffi's limitation caused by some implementations?
> > 
> >  Luís> To my knowledge, yes. AFAICT, only SBCL/x86 and CLISP support
> >  Luís> that.
> > 
> >  Luís> Regarding the behaviour of CFFI:DEFCALLBACK as a non-toplevel
> >  Luís> form, not only will it set it globally, the callback itself won't
> >  Luís> be generated at runtime on most Lisp, IIRC.
> > 
> > I've just ran into the same problem. I really really need closures as
> > callbacks. I've tried the naive approach:
> > 
> > (defmacro object-event-callback-add (obj type function)
> >   `(foreign-funcall "evas_object_event_callback_add"
> >     :pointer ,obj
> >     callback-type ,(foreign-enum-value 'callback-type type)
> >     :pointer (get-callback (defcallback ,(gensym "CB")
> >           :void
> >           ((data :pointer) (cb-e evas) (cb-obj object) (cb-event :pointer))
> >         (funcall ,function cb-e cb-obj cb-event)))
> >     :pointer (null-pointer)))
> > 
> > ... but that's a half-baked solution with too many limitations and only
> > works in a simple example that you run once.
> > 
> > What are the problems with unnamed callbacks? My guess was that they
> > will never get garbage-collected, but how about storing all of these in
> > a table somewhere and explicitly freeing them after they are no longer
> > needed? In my case I do have a way of finding out when a callback is no
> > longer needed, and I suspect this is the case for many other
> > applications.
> 
> The function evas_object_event_callback_add already makes a closure -- on the
> C side.  You can pass arbitrary data as the last argument and it will be
> passed to your callback, so you can make data an integer index into an array
> of Lisp closures.  Since you know when a callback is no longer needed, you can
> recycle the ids quite easily.

Right. I was actually trying to avoid using that. Evas designers are
smart, so they added the "void *data" pointer that gets passed back to
callbacks, but this isn't always the case for all libraries.

If it turns out that it isn't possible to have closures as callbacks on
the Lisp side, I'll probably do just as you described. Thanks for the
suggestion.

--J.



More information about the cffi-devel mailing list