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]; } gsl_complex;
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:
name-and-options ::= structure-name | (structure-name &key constructor deconstructor)
doc-and-slots ::= [docstring] { (slot-name slot-type &key count offset) }*
Define the foreign structure to Lisp. The constructor is
a symbol that when called on the components in order creates a
Lisp object with the same contents as the foreign object; default
is list
. The deconstructor is a symbol that when
called on the Lisp object and a sequence number n selects
the n-th component of that object, or it is a list of
symbols that select the parts of the object in order; default
is elt
.
name-and-options ::= name | (name) name ::= lisp-name [foreign-name] | foreign-name [lisp-name] arguments ::= { (arg-name arg-type) }*
This is used the same as
cffi:defcfun
,
except that options are not supported in name-and-options
.
This is called the same as
cffi:foreign-funcall
,
except that if the name is a symbol (as opposed to a
string), the preparation defined by a
previous fsbv:defcfun
for that function name will
be used.
If foreign-funcall specifies no structures by value in its
list of arguments or return type, it expands
as cffi:foreign-funcall
.
For the C enumeration name which has been defined using
cffi:defcenum
, make auxiliary definitions for
FSBV.
bindings ::= {(var type &optional initial-value)}*
Bind var to a pointer of a foreign object of type type which has optionally been initialized to the initial-value.
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.
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 common-lisp.net>
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.