You find yourself in a dark maze of many twisting
passages...
0.1.1 The Dot-Defs Files
The description of the GTK library consists of several
files, henceforth referred to as dot-defs files. These seem
to originally have been made for the Guile GTK binding, however the
current dot-defs files used in CL-GTK are adapted from those found in
PyGTK, the Python binding by James Henstridge.
The dot-defs files describe the GTK interface in a very
clean way, using S-Expressions that can be trivially parsed. The
definitions are generated in a mostly automatic fashion by some ad-hoc
scripts. There has been the occasional mention of switching to XML
for future versions. Let us pray that this never happens.
Each external function in GTK is defined, along with its
return type, and types and names of its parameters, and so on. Types
are defined, along with their fields, and, if they represent classes,
their superclass. Using this information and some simple templates,
CL-GTK automatically generates code that wraps the GTK library.
0.1.2 The RPC Mechanism
There are two common techniques for making foreign
libraries available to Lisp programs: a foreign linkage (aka. FFI), or
via remote procedure call to a daemon that wraps the foreign
functionality.
Using foreign linkage is potentially simpler, since it
would likely entail writing only Lisp code. Unfortunately, each Lisp
implementation provides a different FFI. That is not an
insurmountable problem. The more important issue is, since foreign
code accessed via an FFI is run "in-process", i.e. in the same memory
region as the Lisp process, Lisp code which uses an FFI is vulnerable
to the same security and correctness problems that might plague code
written in other languages.
Accessing foreign code via RPC entails building a "slave"
daemon which invokes the foreign code as instructed, and writing Lisp
"thunk" procedures which drive the daemon. At least one slave process
must be run in order to use the foreign library. Data is passed
between the Lisp process and the slave via an IPC channel, such as a
pipe or socket.
While it looks more complicated, the RPC approach has
advantages in portability and stability. The only extra-standard
facility required is the ability to run a program and either connect
its input and output to pipes, or open a socket. This will almost
certainly be possible in any Common Lisp implementation. Since GTK is
written in C, and is likely to exhibit a susceptibility to various
well known run-time typing issues that would corrupt memory. Using
RPC allows GTK code to execute in another process, preserving the
sanctity of Lisp code. This is the approach taken by CL-GTK.
0.2 Generating the Glue
First, each dot-defs file is read in, producing data
structures of type TYPE-DEF and FUN-DEF. For each
TYPE-DEF, sending and receiving functions are generated in
both C and Lisp. For each FUN-DEF, Lisp and C thunks are
generated. Thunks are not generated for FUN-DEFs which use
types that were not found in the dot-defs files. All of the generated
functions are assigned a unique service ID number.
The code thus produced is the glue code.