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
.