Functions and Callbacks
defcfun
(ffi:defcfun ("FT_Load_Glyph" ft-load-glyph) ft-error
"Load glyph INDEX of FACE into its slot."
(face :pointer)
(index :uint)
(flags load-flags))
(defcfun ("c_name" lisp-name) result-type [docstring] (argument type)...)
defines a function that converts its arguments as their types say, calls
the C function, and converts the result, or returns no values for
:void. Without a docstring, the function's says which C function it
calls. Its ftype is declaimed from the types, so SBCL checks the
arguments, at compile time where it can. The C name is looked up in every
library loaded.
A :string argument takes a Lisp string, copied for the call and freed
after it, or a pointer as it is. A :string result is a Lisp string, or
nil for a null pointer. (:string :encoding :utf-16le) does the same in
UTF-16LE, and so for the other encodings; see Strings.
(foreign-type-lisp-type type) gives the Lisp type of the values an
argument of type takes, and (foreign-type-lisp-type type :result) the
values type of a call whose result is type: what defcfun declaims,
for a binding made by other means that declaims the same.
(ffi:foreign-type-lisp-type :int32) ; => (SIGNED-BYTE 32)
(ffi:foreign-type-lisp-type :string) ; => (OR STRING FFI:FOREIGN-POINTER)
(ffi:foreign-type-lisp-type :string :result) ; => (VALUES (OR NULL STRING) &OPTIONAL)
(ffi:foreign-type-lisp-type :void :result) ; => (VALUES &OPTIONAL)
Calls without a definition
(ffi:foreign-funcall "abs" :int -3 :int) ; => 3
(ffi:foreign-funcall-pointer (ffi:foreign-symbol-pointer "abs") :int -4 :int)
(ffi:foreign-funcall "free" :pointer (ffi:null-pointer)) ; :VOID, no values
foreign-funcall calls by name and foreign-funcall-pointer through a
pointer: types and arguments in turn, then the result type, :void if it
is left out. With numbers and pointers they allocate nothing.
foreign-symbol-pointer returns a pointer to a C function or variable, or
nil.
Variadic functions
(ffi:with-foreign-pointer-as-string ((buffer size) 64)
(ffi:foreign-funcall-varargs "snprintf" (:pointer buffer :size size :string "%d %.2f")
:int 42 :double 1.5d0 :int))
;; => "42 1.50"
The fixed arguments go in a list, and the variable ones after it, promoted as C promotes them: a float to a double, an integer narrower than int to int. They are passed as the platform's convention for variable arguments asks, on Windows too; see Platforms and Testing.
Callbacks
(ffi:defcallback on-message :void ((level :int) (text :string))
;; Only record the message, on a queue the program drains later.
(record-message level text))
(set-log-function (ffi:callback on-message))
defcallback defines a function C can call; callback, with the name
unevaluated, and get-callback return the pointer to give C. Arguments
and the result convert as their types say: a parameter of a string type
is read in its encoding. A callback cannot return a string type.
Nothing may unwind through C frames. A callback must not let a condition or a non-local exit out of its body: it records what it was told and returns, and the program handles it later. A callback runs on the thread the C code calls it on, which SBCL allows for threads C started.
errno
(errno) returns the errno the last foreign call left. Read it right
after the call whose failure it explains: any other foreign call may
change it. On Windows it is the errno of msvcrt, the C library calls by
name reach there.
The floating-point environment
SBCL unmasks the floating-point traps for invalid operations, division by
zero and overflow; C code assumes them masked.
with-foreign-float-environment masks every trap for the extent of its
body and restores the Lisp's own after, allocating nothing. Call C code
that computes with floats inside it: a GPU driver, for one, may start
threads that inherit the environment of the thread that starts them.