3 Types

Currently the library supports primitive and structure types for arguments and return types.

Primitive types are described using keywords:

:void

The void type. This does not make sense as an argument type.

:int8, :uint8, :int16, :uint16, :int32, :uint32, :int64, :uint64

signed or unsigned integers of the indicated size.

:float, :double

float numbers at the specified precision (32 or 64 bit).

:char, :uchar, :schar, :ushort, :short, :uint, :int, :ulong, :long, :ulonglong, :longlong

Signed or unsigned integers corresponding to the C type of the same name. :char is treated specially because whether it is signed or unsigned is platform-dependent (and also command-line-argument-dependent, though normally this doesn’t matter).

:pointer

A C pointer type. Pointers currently aren’t typed, in the sense that they aren’t differentiated based on what they point to.

:size_t, :ssize_t, :ptrdiff_t, :wchar_t

These correspond to the C type of the same name and internally are just aliases for one of the other integral types.

:bool

Booleans are treated in a Lisp style. As an argument type, nil is converted to a C false value, and other Lisp values are converted to true. As a return type, true is converted to t and false is converted to nil. Note that 0 is not converted to false. If you want a "numeric" boolean type, you can use the size and alignment to find the corresponding primitive type and use that instead.

Structure types are represented by a user-pointer object that wraps an ffi_type. The best way to manipulate structures is to use define-ffi-struct, which is a limited form of cl-defstruct that works on foreign objects directly.

A structure object is also represented by a user-pointer object. If a function’s return type is a structure type, then the object allocated by the FFI will automatically be reclaimed by the garbage collector – there is no need to explicitly free it. (Contrast this with the behavior of ffi-make-c-string, which requires an explicit free.)