Previous: Foreign Types and Lisp Types, Up: Foreign Types
Note: All foreign type names are exported from the sb-alien
package. Some foreign type names are also symbols in
the common-lisp package, in which case they are
reexported from the sb-alien package, so that
e.g. it is legal to refer to sb-alien:single-float.
These are the basic foreign type specifiers:
(* foo) describes a pointer to
an object of type foo. A pointed-to type foo of t
indicates a pointer to anything, similar to void * in
ANSI C. A null alien pointer can be detected with the
sb-alien:null-alien function.
(array foo &rest
dimensions) describes array of the specified dimensions,
holding elements of type foo. Note that (unlike in C) (*
foo) and (array foo) are considered to be
different types when type checking is done. If equivalence of pointer
and array types is desired, it may be explicitly coerced using
sb-alien:cast.
Arrays are accessed using sb-alien:deref, passing the indices
as additional arguments. Elements are stored in column-major order
(as in C), so the first dimension determines only the size of the
memory block, and not the layout of the higher dimensions. An array
whose first dimension is variable may be specified by using nil
as the first dimension. Fixed-size arrays can be allocated as array
elements, structure slots or sb-alien:with-alien
variables. Dynamic arrays can only be allocated using
sb-alien:make-alien.
(sb-alien:struct name &rest
fields) describes a structure type with the specified
name and fields. Fields are allocated at the same offsets
used by the implementation's C compiler, as guessed by the SBCL
internals. An optional :alignment keyword argument can be
specified for each field to explicitly control the alignment of a
field. If name is nil then the structure is anonymous.
If a named foreign struct specifier is passed to
define-alien-type or with-alien, then this defines,
respectively, a new global or local foreign structure type. If no
fields are specified, then the fields are taken
from the current (local or global) alien structure type definition of
name.
(sb-alien:union name &rest
fields) is similar to sb-alien:struct, but describes a
union type. All fields are allocated at the same offset, and the size
of the union is the size of the largest field. The programmer must
determine which field is active from context.
(sb-alien:enum name &rest
specs) describes an enumeration type that maps between integer
values and symbols. If name is nil, then the type is
anonymous. Each element of the specs list is either a Lisp
symbol, or a list (symbol value). value is
an integer. If value is not supplied, then it defaults to one
greater than the value for the preceding spec (or to zero if it is the
first spec).
(sb-alien:signed &optional
bits) specifies a signed integer with the specified number of
bits precision. The upper limit on integer
precision is determined by the machine's word size. If
bits is not specified, the maximum size will be
used.
(integer &optional bits)
is equivalent to the corresponding type specifier using
sb-alien:signed instead of integer.
(sb-alien:unsigned &optional
bits) is like corresponding type specifier using
sb-alien:signed except that the variable is treated as an
unsigned integer.
(boolean &optional bits) is
similar to an enumeration type, but maps from Lisp nil and
t to C 0 and 1 respectively. bits
determines the amount of storage allocated to hold the truth value.
single-float describes a
floating-point number in IEEE single-precision format.
double-float describes a
floating-point number in IEEE double-precision format.
(function result-type &rest
arg-types) describes a foreign function that takes arguments of
the specified arg-types and returns a result of type
result-type. Note that the only context where a foreign
function type is directly specified is in the argument to
sb-alien:alien-funcall. In all other contexts, foreign
functions are represented by foreign function pointer types: (*
(function ...)).
sb-alien:system-area-pointer
describes a pointer which is represented in Lisp as a
system-area-pointer object. SBCL exports this type from
sb-alien because CMUCL did, but tentatively (as of the first
draft of this section of the manual, SBCL 0.7.6) it is deprecated,
since it doesn't seem to be required by user code.
sb-alien:void is used in function
types to declare that no useful value is returned. Using
alien-funcall to call a void foreign function will
return zero values.
(sb-alien:c-string &key external-format
element-type) is similar to (* char), but is interpreted as a
null-terminated string, and is automatically converted into a Lisp
string when accessed; or if the pointer is C NULL or 0,
then accessing it gives Lisp nil.
External format conversion is automatically done when Lisp strings are
passed to foreign code, or when foreign strings are passed to Lisp code.
If the type specifier has an explicit external-format, that
external format will be used. Otherwise a default external format that
has been determined at SBCL startup time based on the current locale
settings will be used. For example, when the following alien routine is
called, the Lisp string given as argument is converted to an
ebcdic octet representation.
(define-alien-routine test int (str (c-string :external-format :ebcdic-us)))
Lisp strings of type base-string are stored with a trailing NUL
termination, so no copying (either by the user or the implementation) is
necessary when passing them to foreign code, assuming that the
external-format and element-type of the c-string
type are compatible with the internal representation of the string. For
an SBCL built with Unicode support that means an external-format
of :ascii and an element-type of base-char. Without
Unicode support the external-format can also be
:iso-8859-1, and the element-type can also be
character. If the external-format or element-type
is not compatible, or the string is a (simple-array character
(*)), this data is copied by the implementation as required.
Assigning a Lisp string to a c-string structure field or
variable stores the contents of the string to the memory already
pointed to by that variable. When a foreign object of type (*
char) is assigned to a c-string, then the
c-string pointer is assigned to. This allows
c-string pointers to be initialized. For example:
(cl:in-package "CL-USER") ; which USEs package "SB-ALIEN"
(define-alien-type nil (struct foo (str c-string)))
(defun make-foo (str)
(let ((my-foo (make-alien (struct foo))))
(setf (slot my-foo 'str) (make-alien char (length str))
(slot my-foo 'str) str)
my-foo))
Storing Lisp NIL in a c-string writes C NULL to
the variable.
sb-alien also exports translations of these C type
specifiers as foreign type specifiers: sb-alien:char,
sb-alien:short, sb-alien:int,
sb-alien:long, sb-alien:unsigned-char,
sb-alien:unsigned-short,
sb-alien:unsigned-int,
sb-alien:unsigned-long, sb-alien:float, and
sb-alien:double.