You are looking at historical revision 1626 of this page. It may differ significantly from its current revision.

Here is an example for a simple program that uses CHICKEN's foreign function interface. It is the Gtk 2.0 Hello, world program as presented in the GTK tutorial, which is available here.

This example is intended to show various features of the FFI and to demonstrate that one can go relatively far without writing tons of glue code. The comments are only to show the CHICKEN specific things, see the original tutorial for more information.

 ;;;; gtkhello.scm

 ;; Include this code directly into generated .c file:

 #include <gtk/gtk.h>

 ;; Parse declarations and generate Scheme bindings:

 /* We just need a declaration, so this is sufficient: */

 void gtk_main_quit();
 void gtk_init(int *, char ***);
 GtkWidget *gtk_window_new(int);
 int g_signal_connect(void *, char *, void *, void *);
 int g_signal_connect_swapped(void *, char *, void *, void *);
 void gtk_container_set_border_width(GtkContainer *, int);
 GtkWidget *gtk_button_new_with_label(char *);
 void gtk_widget_destroy(GtkWidget *);
 void gtk_container_add(GtkContainer *, GtkWidget *);
 void gtk_widget_show(GtkWidget *);

 /* the ___callback marker is needed, because gtk_main() may
   (and will) call Scheme callbacks. */
 ___callback void gtk_main();

 ;; Define a few callback function:

 (define-external (hello ((c-pointer GtkWidget) widget) 
			 (c-pointer data)) 
   (print Hello, world) )

 (define-external (delete_event ((c-pointer GtkWidget) widget)
				((c-pointer GdkEvent) event)
				(c-pointer data) )
   (print delete event occurred)

 (define-external (destroy ((c-pointer GtkWidget) widget)
			   (c-pointer data) )
   (gtk_main_quit) )

 ;; This is a bit ugly, but there is no elegant way to get
 ;; at argc/argv at the Scheme level and pass pointers to it
 ;; to foreign code:

 (foreign-code gtk_init(&C_main_argc, &C_main_argv);)

 (define window (gtk_window_new GTK_WINDOW_TOPLEVEL))

 ;; $#... with a callback-name returns the function pointer:

 (g_signal_connect window delete_event #$delete_event #f)
 (g_signal_connect window destroy #$destroy #f)

 (gtk_container_set_border_width window 10)

 (define button (gtk_button_new_with_label "Hello World"))

 (g_signal_connect button clicked #$hello #f)

 ;; Here we use foreign-value to get the function pointer.
 ;; #$gtk_widget_destroy wouldn't work: the function is not
 ;; a callback:

 (g_signal_connect_swapped button clicked 
   (foreign-value gtk_widget_destroy c-pointer) window)

 (gtk_container_add window button)
 (gtk_widget_show button)
 (gtk_widget_show window)

To compile it, we have to ensure the proper C compiler and linker flags are passed:

$ csc -vk gtkhello.scm -C "`pkg-config --cflags gtk+-2.0`" -L "`pkg-config --libs gtk+-2.0`" -X easyffi

(the easyffi egg is required)