Foreign Variables

Both local (stack allocated) and external (C global) foreign variables are supported.

Local Foreign Variables

(sb-alien:with-alien var-definitions &body body)

The with-alien macro establishes local foreign variables with the specified alien types and names. This form is analogous to defining a local variable in C: additional storage is allocated, and the initial value is copied. This form is less analogous to LET-allocated Lisp variables, since the variables can't be captured in closures: they live only for the dynamic extent of the body, and referring to them outside is a gruesome error.

The var-definitions argument is a list of variable definitions, each of the form

(name type &optional initial-value)
The names of the variables are established as symbol-macros; the bindings have lexical scope, and may be assigned with setq or setf.

The with-alien macro also establishes a new scope for named structures and unions. Any type specified for a variable may contain named structure or union types with the slots specified. Within the lexical scope of the binding specifiers and body, a locally defined foreign structure type foo can be referenced by its name using (struct foo).

External Foreign Variables

External foreign names are strings, and Lisp names are symbols. When an external foreign value is represented using a Lisp variable, there must be a way to convert from one name syntax into the other. The macros extern-alien, define-alien-variable and define-alien-routine use this conversion heuristic:

(sb-alien:define-alien-variable name type)

The define-alien-variable macro defines name as an external foreign variable of the specified foreign type. name and type are not evaluated. The Lisp name of the variable (see above) becomes a global alien variable. Global alien variables are effectively ``global symbol macros''; a reference to the variable fetches the contents of the external variable. Similarly, setting the variable stores new contents---the new contents must be of the declared type. Someday, they may well be implemented using the ANSI define-symbol-macro mechanism, but as of SBCL 0.7.5, they are still implemented using an older more-or-less parallel mechanism inherited from CMU CL.

For example, to access a C-level counter foo, one could write

(define-alien-variable "foo" int)
;; Now it is possible to get the value of the C variable foo simply by
;; referencing that Lisp variable:
(print foo)
(setf foo 14)
(incf foo)

(sb-alien:get-errno)

Since in modern C libraries, the errno "variable" is typically no longer a variable, but some bizarre artificial construct which behaves superficially like a variable within a given thread, it can no longer reliably be accessed through the ordinary define-alien-variable mechanism. Instead, SBCL provides the operator sb-alien:get-errno to allow Lisp code to read it.

(sb-alien:extern-alien name type)

The extern-alien macro returns an alien with the specified type which points to an externally defined value. name is not evaluated, and may be either a string or a symbol. type is an unevaluated alien type specifier.