@chapter Foreign Function Interface
This chapter describes SBCL's interface to C programs and
-libraries (and, since C interfaces are a sort of @emph{ingua
+libraries (and, since C interfaces are a sort of @emph{lingua
franca} of the Unix world, to other programs and libraries in
general.)
* Operations On Foreign Values::
* Foreign Variables::
* Foreign Data Structure Examples::
-* Loading Unix Object Files::
+* Loading Shared Object Files::
* Foreign Function Calls::
* Step-By-Step Example of the Foreign Function Interface::
@end menu
SBCL, like CMUCL before it, relies primarily on the automatic
conversion and direct manipulation approaches. The @code{SB-ALIEN}
-package provices a facility wherein foreign values of simple scalar
+package provides a facility wherein foreign values of simple scalar
types are automatically converted and complex types are directly
manipulated in their foreign representation. Additionally the
lower-level System Area Pointers (or @acronym{SAP}s) can be used where
The foreign type specifier @code{(sb-alien:struct @var{name} &rest
@var{fields})} describes a structure type with the specified
@var{name} and @var{fields}. Fields are allocated at the same offsets
-used by the implementation's C compiler. If @var{name} is @code{nil}
-then the structure is anonymous.
+used by the implementation's C compiler, as guessed by the SBCL
+internals. An optional @code{:alignment} keyword argument can be
+specified for each field to explicitly control the alignment of a
+field. If @var{name} is @code{nil} then the structure is anonymous.
If a named foreign @code{struct} specifier is passed to
@code{define-alien-type} or @code{with-alien}, then this defines,
@item
The foreign type specifier @code{(sb-alien:enum @var{name} &rest
@var{specs})} describes an enumeration type that maps between integer
-values and keywords. If @var{name} is @code{nil}, then the type is
+values and symbols. If @var{name} is @code{nil}, then the type is
anonymous. Each element of the @var{specs} list is either a Lisp
-keyword, or a list @code{(@var{keyword} @var{value})}. @var{value} is
+symbol, or a list @code{(@var{symbol} @var{value})}. @var{value} is
an integer. If @var{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).
return zero values.
@item
-The foreign type specifier @code{sb-alien:c-string} is similar to
-@code{(* 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 @code{NULL} or @code{0}, then accessing it gives Lisp
-@code{nil}. Lisp strings 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.
+The foreign type specifier @code{(sb-alien:c-string &key external-format
+element-type)} is similar to @code{(* 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 @code{NULL} or @code{0},
+then accessing it gives Lisp @code{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 @code{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
+@code{ebcdic} octet representation.
+
+@lisp
+(define-alien-routine test int (str (c-string :external-format :ebcdic-us)))
+@end lisp
+
+Lisp strings of type @code{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
+@code{external-format} and @code{element-type} of the @code{c-string}
+type are compatible with the internal representation of the string. For
+an SBCL built with Unicode support that means an @code{external-format}
+of @code{:ascii} and an @code{element-type} of @code{base-char}. Without
+Unicode support the @code{external-format} can also be
+@code{:iso-8859-1}, and the @code{element-type} can also be
+@code{character}. If the @code{external-format} or @code{element-type}
+is not compatible, or the string is a @code{(simple-array character
+(*))}, this data is copied by the implementation as required.
Assigning a Lisp string to a @code{c-string} structure field or
variable stores the contents of the string to the memory already
value.
@end defun
-@defun sb-alien:slot @var{struct-or-union} &rest @var{slot-names}
+@defun sb-alien:slot @var{struct-or-union} @var{slot-name}
@findex slot
The @code{sb-alien:slot} function extracts the value of the slot named
The @code{sb-alien:sap-alien} function converts @var{sap} (a system
area pointer) to a foreign value with the specified
-@var{type}. @var{type} is not evaluated. </para>
+@var{type}. @var{type} is not evaluated.
The @var{type} must be some foreign pointer, array, or record type.
@end defun
-@defun sb-alien:alien-sap @var{foreign-value} @var{type}
+@defun sb-alien:alien-sap @var{foreign-value}
@findex alien-sap
The @code{sb-alien:alien-sap} function returns the @acronym{SAP} which
(setq my-struct (slot my-struct 'n))
@end lisp
-@node Loading Unix Object Files
+@node Loading Shared Object Files
@comment node-name, next, previous, up
-@section Loading Unix Object Files
+@section Loading Shared Object Files
Foreign object files can be loaded into the running Lisp process by
calling @code{load-shared-object}.
-The @code{sb-alien:load-shared-object} loads a single object file into
-the currently running Lisp. The external symbols defining routines and
-variables are made available for future external references (e.g. by
-@code{extern-alien}). Forward references to foreign symbols aren't
-supported: @code{load-shared-object} must be run before any of the
-defined symbols are referenced.
-
-@quotation
-Note: As of SBCL 0.7.5, all foreign code (code loaded with
-@code{load-shared-object}) is lost when a Lisp
-core is saved with @code{sb-ext:save-lisp-and-die}, and no attempt is
-made to restore it when the core is loaded. Historically this has been
-an annoyance both for SBCL users and for CMUCL users. It's hard to
-solve this problem completely cleanly, but some generally-reliable
-partial solution might be useful. Once someone in either camp gets
-sufficiently annoyed to create it, SBCL is likely to adopt some
-mechanism for automatically restoring foreign code when a saved core
-is loaded.
-@end quotation
-
+@include fun-sb-alien-load-shared-object.texinfo
@node Foreign Function Calls
@comment node-name, next, previous, up
printf("s = %s\n", s);
printf("r->x = %d\n", r->x);
printf("r->s = %s\n", r->s);
- for (j = 0; j < 10; j++) printf("a[%d] = %d.\n", j, a[j]);
+ for (j = 0; j < 10; j++) printf("a[%d] = %d.\n", j, a[j]);
r2 = (struct c_struct *) malloc (sizeof(struct c_struct));
r2->x = i + 5;
r2->s = "a C string";
order to enable incremental loading with some linkers, you may need to
say @samp{cc -G 0 -c test.c})
-Once the C code has been compiled, you can start up Lisp and load it
-in: @samp{sbcl} Lisp should start up with its normal prompt.
+Once the C code has been compiled, you can start up Lisp and load it in:
+@samp{sbcl}. Lisp should start up with its normal prompt.
Within Lisp, compile the Lisp file. (This step can be done
separately. You don't have to recompile every time.)
@samp{(compile-file "test.lisp")}
Within Lisp, load the foreign object file to define the necessary
-symbols: @samp{(load-shared-object "test.so")}. This must be done
-before loading any code that refers to these symbols.
+symbols: @samp{(load-shared-object "test.so")}.
Now you can load the compiled Lisp (``fasl'') file into Lisp:
@samp{(load "test.fasl")}