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

Martin Simmons martin at lispworks.com
Mon Feb 6 15:56:54 UTC 2006


>>>>> On Sun, 05 Feb 2006 14:41:59 +0100, Jan Rychter <jan at rychter.com> said:
> Delivered-To: cffi-devel at common-lisp.net
> 
> I wrote:
> > > >>>>> 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.
> 
> Ok, after actually trying this out, there are two major problems:
> 
> 1. This approach works just fine for adding callbacks, but fails for
>    deleting them. The problem is that the C side insists on identifying
>    callbacks to delete by a function pointer. In this approach all
>    callbacks would get the same function pointer on the C side -- that
>    of the dispatching callback function on the Lisp side. Which means I
>    won't be able to delete them on the C side afterwards.

Bleuch, other window systems have managed to do this right.

You could overcome this by only installing 1 evas callback and keeping the
list of Lisp callbacks entirely on the Lisp side.  Remove the evas callback
when there are no more Lisp callbacks.


> 2. I was actually wrong when I said I knew when the callback would be no
>    longer needed. Not quite sure what to do about this yet. I know next
>    to nothing about finalizers -- can I expect them to be supported?

Finalizers are not related to the FFI really, so will be
implementation-specific.

__Martin



More information about the cffi-devel mailing list