X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=doc%2Fmanual%2Fffi.texinfo;h=b4fc8cae4a1e668ad1ff604f715be0bb0e98c2cd;hb=a01e7ac2e8a9f3afae8f759381a0829fceb5bfde;hp=e028c0c3e372d0a5fe3676b4bac40615619a28e4;hpb=192731b882467a9014b64b1eb097c8000441da31;p=sbcl.git diff --git a/doc/manual/ffi.texinfo b/doc/manual/ffi.texinfo index e028c0c..b4fc8ca 100644 --- a/doc/manual/ffi.texinfo +++ b/doc/manual/ffi.texinfo @@ -1,9 +1,9 @@ -@node The Foreign Function Interface +@node Foreign Function Interface @comment node-name, next, previous, up -@chapter The Foreign Function Interface +@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.) @@ -24,7 +24,7 @@ notably in the name of the @code{SB-ALIEN} package. * 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 @@ -64,7 +64,7 @@ use of extensions to the Lisp language. 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 @@ -174,7 +174,7 @@ ANSI C. A null alien pointer can be detected with the @code{sb-alien:null-alien} function. @item -The foreign type specifier @code{(array @var{foo} &optional +The foreign type specifier @code{(array @var{foo} &rest dimensions)} describes array of the specified @code{dimensions}, holding elements of type @var{foo}. Note that (unlike in C) @code{(* @var{foo})} and @code{(array @var{foo})} are considered to be @@ -196,8 +196,10 @@ variables. Dynamic arrays can only be allocated using 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, @@ -216,9 +218,9 @@ determine which field is active from context. @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). @@ -281,13 +283,37 @@ types to declare that no useful value is returned. Using 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 @@ -355,7 +381,7 @@ array type. @code{deref} can be set with @code{setf} to assign a new 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 @@ -436,7 +462,7 @@ argument, but it does refer to the same foreign data bits. 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. +@var{type}. @var{type} is not evaluated. The @var{type} must be some foreign pointer, array, or record type. @end defun @@ -711,33 +737,14 @@ which can be manipulated in Lisp like this: (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-1-function} or @code{load-function}) 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 @@ -1138,7 +1145,7 @@ struct c_struct *c_function (i, s, r, a) 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"; @@ -1201,16 +1208,15 @@ routine, e.g.: @samp{cc -c test.c && ld -shared -o test.so test.o} (In 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")}