Foreign Structures By Value (FSBV)


Call foreign functions when one or more arguments and/or the return value are structures. In CFFI and most Lisp foreign interfaces, structures must be passed by reference, that is, as pointers. FSBV permits calling them by value. It requires CFFI and libffi.


For example, the complex type is defined in the GNU Scientific Library (GSL) as

typedef struct
    double dat[2];

The function gsl_complex_conjugate takes and returns a structure of this type by value,

gsl_complex gsl_complex_conjugate (gsl_complex z);

If we define

(defcstruct (complex :constructor complex :deconstructor (realpart imagpart))
  (dat :double :count 2))
(defcfun (complex-conjugate "gsl_complex_conjugate") complex
  (c complex))
then we can call this function from Lisp:
(complex-conjugate #c(3.0d0 4.0d0))
#C(3.0 -4.0)


The following definitions provide the call by value capability, and provide a convenient way of making equivalent Lisp and foreign objects:

There are also functions fsbv:object and (setf fsbv:object) that create the Lisp object from the foreign pointer and type, and vice versa. They are used internally but are exported for the convenience of users. When FSBV is loaded, it will put :fsbv in *features*.

Note: all arguments to the function, and the return value, will gain an additional layer of indirection. This means that arguments normally sent by reference (as a pointer) will require a pointer to the pointer.

Installation note

Because different platforms and package managers install libffi in different places, it is hard to provide the proper path to ffi.h for every installation. If the file is not found, you will need to find it yourself (try pkg-config --cflags-only-I libffi) and specify the path in a cc-flags form in libffi-unix.lisp; note the Darwin example there. If yours is a common installation/platform and the path is not highly specific to a libffi version number (e.g. nothing like /usr/lib64/libffi-3.0.8/include which will be obsolete when 3.0.9 is installed), send the form to me at the address below and I will incorporate it into the file.


Copyright © 2009, 2010 Liam Healy <lhealy at>

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

The software is provided “as is”, without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or the use or other dealings in the software.

Time-stamp: <2010-06-11 11:24:39EDT readme.html>