[plt-scheme] Questions about modules, compilation, namespaces, planet and ffi

From: Daniel Pinto de Mello e Silva (daniel.silva at gmail.com)
Date: Mon May 9 14:01:53 EDT 2005

On 5/5/05, Bruno Deferrari <utizoc at gmail.com> wrote:
> ...
> ; C definition :
> ; void ecore_evas_callback_resize_set(Ecore_Evas *ee,
> ;                                     void (*func) (Ecore_Evas *ee));
> 
> (defecore-evas* ecore-evas-callback-resize-set :
>   _EcoreEvas (_fun _EcoreEvas -> _void)
>   -> _void)
> 

Be careful that the lambda you pass to ecore-evas-callback-resize-set
may be garbage-collected, and then libevas will call back into garbage
and your program will explode.

When I was looking at the EFL, I was playing with EWL instead of Evas
but the idea here is the same: bind the C function that accepts a
callback privately, then export a different function that saves the
Scheme callback until it's no longer needed.  In the case of EWL, it's
not needed after the Widget object is destroyed.

Here's a simple implementation:

(define ewl (ffi-lib "libewl.so"))

(define _Ewl_Callback_Function
    (_fun _Ewl_Widget-pointer _pointer _pointer -> _bool))

  ;; private
  (define ewl-callback-append
    (get-ffi-obj "ewl_callback_append" ewl
                 (_fun _Ewl_Widget-pointer
                         _Ewl_Callback_Type
                         _Ewl_Callback_Function
                        (_pointer = #f) ; "user data," unused C-ism
                        -> _int)))

  (define *callbacks* (make-hash-table))

  ;; public
  (define (append-callback widget cb-type cb-proc)
    (define clear-key (gensym))
    (define cb-key (gensym))
     ;; clear is a finalizer
    (define (clear w evt data)
      (hash-table-remove! *callbacks* clear-key)
      (hash-table-remove! *callbacks* cb-key))
    ;; cb wraps cb-proc because of the _void issue Eli talked about
    (define (cb w evt data)
      (cb-proc w evt)
      #f)
    (hash-table-put! *callbacks* clear-key clear)
    (hash-table-put! *callbacks* cb-key cb)
    (ewl-callback-append widget 'EWL_CALLBACK_DESTROY clear)
    (ewl-callback-append widget cb-type cb))


Daniel



Posted on the users mailing list.