4 For cffi Users
dxtr edited this page 2026-10-18 15:16:26 +02:00

For cffi Users

cl-ffi has cffi's names, and what they do is cffi's, for what cl-ffi has. A cffi pointer is a cl-ffi pointer: both are SBCL's system-area pointers. So a program may use cffi for a library of its own beside libraries built on cl-ffi, and pass pointers between them.

What cl-ffi has

Area Operators
Pointers foreign-pointer, pointerp, null-pointer, null-pointer-p, pointer-eq, pointer-address, make-pointer, inc-pointer
Memory foreign-alloc, foreign-free, with-foreign-object, with-foreign-objects, with-foreign-pointer, mem-ref, mem-aref, mem-aptr, with-pointer-to-vector-data, foreign-type-size, foreign-type-alignment
Types defctype, defcenum, defbitfield, defcstruct, defcunion, foreign-slot-value, foreign-slot-pointer, foreign-slot-offset, foreign-slot-type, with-foreign-slots, foreign-enum-value, foreign-enum-keyword, foreign-enum-keyword-list, foreign-bitfield-value, foreign-bitfield-symbols, foreign-bitfield-symbol-list
Functions defcfun, foreign-funcall, foreign-funcall-pointer, foreign-funcall-varargs, foreign-symbol-pointer, defcallback, callback, get-callback
Strings foreign-string-to-lisp, lisp-string-to-foreign, foreign-string-alloc, foreign-string-free, with-foreign-string, with-foreign-pointer-as-string
Libraries define-foreign-library, use-foreign-library, load-foreign-library, foreign-library-loaded-p, foreign-library-pathname

What differs

  • Scalars only through mem-ref. mem-ref, mem-aref and foreign-slot-value read and write scalars. For an array slot cffi gives a pointer, and for a struct it builds a plist; cl-ffi refuses both, at compile time when the type is constant, and names foreign-slot-pointer and mem-aptr, which give pointers.
  • No calling conventions. x86-64 and AArch64 have one C calling convention, Windows included, so defcfun and defcallback take no :convention.
  • No structs by value, foreign variables or type translators. Pass a pointer to a struct; read a variable through foreign-symbol-pointer.
  • foreign-funcall-pointer takes no list of options: (foreign-funcall-pointer pointer :int x :int).
  • foreign-symbol-pointer takes no :library: it looks in every library loaded, as cffi's did on SBCL.
  • Strict strings, both ways. A character an encoding cannot represent signals an encoding-error, and bytes that are no valid string a decoding-error. babel, under cffi, decoded as strictly but encoded a lone surrogate without complaint. The encodings are UTF-8, the default, UTF-16LE, UTF-16BE and Latin-1, and (:string :encoding :utf-16le) is a string type in one, as in cffi.
  • No global settings. There is no *default-foreign-encoding*, the default being UTF-8, and no *foreign-library-directories*: a library spec gives a name the system searches for, or a full path.
  • Platform keywords. A library clause's condition tests cl-ffi's platform keywords, :windows, :unix, :linux and :darwin, as well as *features*. :windows holds on Windows, though SBCL sets only :win32 itself; under cffi, :windows came from trivial-features.
  • defcfun declaims an ftype, from the function's C types.
  • Saved images load libraries again from their definitions, not from the paths they were loaded from, and run the hooks add-image-start-hook added.
  • Errors are conditions of type ffi-error.

What cl-ffi adds

  • errno: the errno the last foreign call left.
  • with-foreign-float-environment: the floating-point traps masked, as C code expects them.
  • add-image-start-hook: code to run when a saved image starts, after its libraries are loaded again.