X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=doc%2Fmanual%2Fffi.texinfo;h=0c4eb4945875a66264c11a3be5ea49e4c3b3d2b0;hb=979539d20a27f4315db9e1bde0a4413135cf8603;hp=68d5ccec44d6ffde80ec874ff21586ecbdaee828;hpb=78867137cd2b9e689fd07640d60e4cf3942bf719;p=sbcl.git diff --git a/doc/manual/ffi.texinfo b/doc/manual/ffi.texinfo index 68d5cce..0c4eb49 100644 --- a/doc/manual/ffi.texinfo +++ b/doc/manual/ffi.texinfo @@ -1,9 +1,9 @@ -@node The Foreign Function Interface, Function Index, Beyond The ANSI Standard, Top +@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,12 +24,12 @@ 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 -@node Introduction to the Foreign Function Interface, Foreign Types, The Foreign Function Interface, The Foreign Function Interface +@node Introduction to the Foreign Function Interface @comment node-name, next, previous, up @section Introduction to the Foreign Function Interface @c AKA "Introduction to Aliens" in the CMU CL manual @@ -49,12 +49,11 @@ by the Lisp implementation. This can require a considerable amount of dependent on the internal implementation details of the Lisp system. @item -The Lisp system can automatically convert objects back and forth -between the Lisp and foreign representations. This is convenient, but +The Lisp system can automatically convert objects back and forth between +the Lisp and foreign representations. This is convenient, but translation becomes prohibitively slow when large or complex data structures must be shared. This approach is supported by the SBCL -@acronym{FFI}, and used automatically by the when passing integers and -strings. +@acronym{FFI}, and used automatically when passing integers and strings. @item The Lisp program can directly manipulate foreign objects through the @@ -64,7 +63,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 @@ -79,7 +78,7 @@ raw pointer to the foreign data within an @code{alien-value} object. The type language and operations on foreign types are intentionally similar to those of the C language. -@node Foreign Types, Operations On Foreign Values, Introduction to the Foreign Function Interface, The Foreign Function Interface +@node Foreign Types @comment node-name, next, previous, up @section Foreign Types @c AKA "Alien Types" in the CMU CL manual @@ -109,7 +108,7 @@ has the corresponding SBCL @acronym{FFI} type * Foreign Type Specifiers:: @end menu -@node Defining Foreign Types, Foreign Types and Lisp Types, Foreign Types, Foreign Types +@node Defining Foreign Types @comment node-name, next, previous, up @subsection Defining Foreign Types @@ -127,7 +126,7 @@ An anonymous structure or union type is specified by using the name inherently named, but can be given named abbreviations using the @code{define-alien-type} macro. -@node Foreign Types and Lisp Types, Foreign Type Specifiers, Defining Foreign Types, Foreign Types +@node Foreign Types and Lisp Types @comment node-name, next, previous, up @subsection Foreign Types and Lisp Types @@ -153,7 +152,7 @@ to Lisp floats. When @code{type-of} is called on an alien value that is not automatically converted to a Lisp value, then it will return an @code{alien} type specifier. -@node Foreign Type Specifiers, , Foreign Types and Lisp Types, Foreign Types +@node Foreign Type Specifiers @comment node-name, next, previous, up @subsection Foreign Type Specifiers @@ -174,7 +173,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 +195,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 +217,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 +282,40 @@ 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 +@cindex External formats +The foreign type specifier @code{(sb-alien:c-string &key +external-format element-type not-null)} 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. +@code{nil} unless @code{not-null} is true, in which case a type-error +is signalled. + +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 @@ -313,17 +341,21 @@ the variable. @item @code{sb-alien} also exports translations of these C type -specifiers as foreign type specifiers: @code{sb-alien:char}, -@code{sb-alien:short}, @code{sb-alien:int}, -@code{sb-alien:long}, @code{sb-alien:unsigned-char}, -@code{sb-alien:unsigned-short}, -@code{sb-alien:unsigned-int}, -@code{sb-alien:unsigned-long}, @code{sb-alien:float}, and -@code{sb-alien:double}. +specifiers as foreign type specifiers: +@code{char}, +@code{short}, +@code{int}, +@code{long}, +@code{unsigned-char}, +@code{unsigned-short}, +@code{unsigned-int}, +@code{unsigned-long}, +@code{float}, @code{double}, +@code{size-t}, and @code{off-t}. @end itemize -@node Operations On Foreign Values, Foreign Variables, Foreign Types, The Foreign Function Interface +@node Operations On Foreign Values @comment node-name, next, previous, up @section Operations On Foreign Values @c AKA "Alien Operations" in the CMU CL manual @@ -338,11 +370,11 @@ to dynamically allocate and free foreign variables. * Foreign Dynamic Allocation:: @end menu -@node Accessing Foreign Values, Coercing Foreign Values, Operations On Foreign Values, Operations On Foreign Values +@node Accessing Foreign Values @comment node-name, next, previous, up @subsection Accessing Foreign Values -@defun sb-alien:deref @var{pointer-or-array} &rest @var{indices} +@defun @sbalien{deref} @var{pointer-or-array} &rest @var{indices} The @code{sb-alien:deref} function returns the value pointed to by a foreign pointer, or the value of a foreign array element. When @@ -352,11 +384,10 @@ the size of the type pointed to. When dereferencing an array, the number of indices must be the same as the number of dimensions in the 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 @sbalien{slot} @var{struct-or-union} @var{slot-name} + The @code{sb-alien:slot} function extracts the value of the slot named @var{slot-name} from a foreign @code{struct} or @code{union}. If @var{struct-or-union} is a pointer to a structure or union, then it is @@ -377,20 +408,20 @@ to and from integers - raw machine addresses. They should thus be used with caution; corrupting the Lisp heap or other memory with @acronym{SAP}s is trivial. -@defun sb-sys:int-sap @var{machine-address} +@defun @sbsys{int-sap} @var{machine-address} Creates a @acronym{SAP} pointing at the virtual address @var{machine-address}. @end defun -@defun sb-sys:sap-ref-32 @var{sap} @var{offset} +@defun @sbsys{sap-ref-32} @var{sap} @var{offset} Access the value of the memory location at @var{offset} bytes from @var{sap}. This form may also be used with @code{setf} to alter the memory at that location. @end defun -@defun sb-sys:sap= @var{sap1} @var{sap2} +@defun @sbsys{sap=} @var{sap1} @var{sap2} Compare @var{sap1} and @var{sap2} for equality. @end defun @@ -404,37 +435,37 @@ use @code{apropos} and @code{describe} for more details @end lisp -@node Coercing Foreign Values, Foreign Dynamic Allocation, Accessing Foreign Values, Operations On Foreign Values +@node Coercing Foreign Values @comment node-name, next, previous, up @subsection Coercing Foreign Values -@defun sb-alien:addr @var{alien-expr} - +@defmac @sbalien{addr} @var{alien-expr} + The @code{sb-alien:addr} macro returns a pointer to the location specified by @var{alien-expr}, which must be either a foreign variable, a use of @code{sb-alien:deref}, a use of @code{sb-alien:slot}, or a use of @code{sb-alien:extern-alien}. -@end defun +@end defmac + +@defmac @sbalien{cast} @var{foreign-value} @var{new-type} -@defun sb-alien:cast @var{foreign-value} @var{new-type} - The @code{sb-alien:cast} macro converts @var{foreign-value} to a new foreign value with the specified @var{new-type}. Both types, old and new, must be foreign pointer, array or function types. Note that the resulting Lisp foreign variable object is not @code{eq} to the argument, but it does refer to the same foreign data bits. -@end defun +@end defmac -@defun sb-alien:sap-alien @var{sap} @var{type} - -The @code{sb-alien:sap-alien} function converts @var{sap} (a system +@defmac @sbalien{sap-alien} @var{sap} @var{type} + +The @code{sb-alien:sap-alien} macro 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 +@end defmac -@defun sb-alien:alien-sap @var{foreign-value} @var{type} +@defun @sbalien{alien-sap} @var{foreign-value} The @code{sb-alien:alien-sap} function returns the @acronym{SAP} which points to @var{alien-value}'s data. @@ -444,67 +475,22 @@ record type. @end defun -@node Foreign Dynamic Allocation, , Coercing Foreign Values, Operations On Foreign Values +@node Foreign Dynamic Allocation @comment node-name, next, previous, up @subsection Foreign Dynamic Allocation Lisp code can call the C standard library functions @code{malloc} and -@code{free} to dynamically allocate and deallocate foreign -variables. The Lisp code shares the same allocator with foreign C -code, so it's OK for foreign code to call @code{free} on the result of -Lisp @code{sb-alien:make-alien}, or for Lisp code to call -@code{sb-alien:free-alien} on foreign objects allocated by C -code. - -@defmac sb-alien:make-alien @var{type} @var{size} - -The @code{sb-alien:make-alien} macro -returns a dynamically allocated foreign value of the specified -@var{type} (which is not evaluated.) The allocated memory is not -initialized, and may contain arbitrary junk. If supplied, -@var{size} is an expression to evaluate to compute the size of the -allocated object. There are two major cases: +@code{free} to dynamically allocate and deallocate foreign variables. +The Lisp code shares the same allocator with foreign C code, so it's +OK for foreign code to call @code{free} on the result of Lisp +@code{sb-alien:make-alien}, or for Lisp code to call +@code{sb-alien:free-alien} on foreign objects allocated by C code. -@itemize -@item -When @var{type} is a foreign array type, an array of that type is -allocated and a pointer to it is returned. Note that you must use -@code{deref} to change the result to an array before you can use -@code{deref} to read or write elements: - -@lisp -(cl:in-package "CL-USER") ; which USEs package "SB-ALIEN" -(defvar *foo* (make-alien (array char 10))) -(type-of *foo*) @result{} (alien (* (array (signed 8) 10))) -(setf (deref (deref foo) 0) 10) @result{} 10 -@end lisp - -If supplied, @var{size} is used as the first dimension for the - array. +@include macro-sb-alien-make-alien.texinfo +@include fun-sb-alien-make-alien-string.texinfo +@include fun-sb-alien-free-alien.texinfo -@item -When @var{type} is any other foreign type, then an object for that -type is allocated, and a pointer to it is returned. So -@code{(make-alien int)} returns a @code{(* int)}. If @var{size} is -specified, then a block of that many objects is allocated, with the -result pointing to the first one. - -@end itemize - -@end defmac - -@defun sb-alien:free-alien @var{foreign-value} - -The @code{sb-alien:free-alien} function -frees the storage for @var{foreign-value}, -which must have been allocated with Lisp @code{make-alien} -or C @code{malloc}. - -See also the @code{sb-alien:with-alien} macro, which allocates foreign -values on the stack. -@end defun - -@node Foreign Variables, Foreign Data Structure Examples, Operations On Foreign Values, The Foreign Function Interface +@node Foreign Variables @comment node-name, next, previous, up @section Foreign Variables @c AKA "Alien Variables" in the CMU CL manual @@ -517,11 +503,11 @@ are supported. * External Foreign Variables:: @end menu -@node Local Foreign Variables, External Foreign Variables, Foreign Variables, Foreign Variables +@node Local Foreign Variables @comment node-name, next, previous, up @subsection Local Foreign Variables -@defmac sb-alien:with-alien @var{var-definitions} &body @var{body} +@defmac @sbalien{with-alien} @var{var-definitions} &body @var{body} The @code{with-alien} macro establishes local foreign variables with the specified alien types and names. This form is analogous to @@ -549,7 +535,7 @@ defined foreign structure type @var{foo} can be referenced by its name using @code{(struct @var{foo})}. @end defmac -@node External Foreign Variables, , Local Foreign Variables, Foreign Variables +@node External Foreign Variables @comment node-name, next, previous, up @subsection External Foreign Variables @@ -579,7 +565,7 @@ specified by using a list of the form @end itemize -@defmac sb-alien:define-alien-variable @var{name} @var{type} +@defmac @sbalien{define-alien-variable} @var{name} @var{type} The @code{define-alien-variable} macro defines @var{name} as an external foreign variable of the specified foreign @code{type}. @@ -605,7 +591,7 @@ For example, to access a C-level counter @var{foo}, one could write @end lisp @end defmac -@defun sb-alien:get-errno +@defun @sbalien{get-errno} Since in modern C libraries, the @code{errno} ``variable'' is typically no longer a variable, but some bizarre artificial construct @@ -615,7 +601,7 @@ it can no longer reliably be accessed through the ordinary the operator @code{sb-alien:get-errno} to allow Lisp code to read it. @end defun -@defmac sb-alien:extern-alien @var{name} @var{type} +@defmac @sbalien{extern-alien} @var{name} @var{type} The @code{extern-alien} macro returns an alien with the specified @var{type} which points to an externally defined value. @var{name} is @@ -623,7 +609,7 @@ not evaluated, and may be either a string or a symbol. @var{type} is an unevaluated alien type specifier. @end defmac -@node Foreign Data Structure Examples, Loading Unix Object Files, Foreign Variables, The Foreign Function Interface +@node Foreign Data Structure Examples @comment node-name, next, previous, up @section Foreign Data Structure Examples @c AKA "Alien Data Structure Example" in the CMU CL manual @@ -697,42 +683,18 @@ which can be manipulated in Lisp like this: (setq my-struct (slot my-struct 'n)) @end lisp -@node Loading Unix Object Files, Foreign Function Calls, Foreign Data Structure Examples, The Foreign Function Interface +@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 the functions @code{load-foreign} or @code{load-1-foreign}. - -The @code{sb-alien:load-1-foreign} function is the more primitive of -the two operations. It 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-1-foreign} must be run before any of the defined -symbols are referenced. - -@code{sb-alien:load-foreign} is built in terms of -@code{load-1-foreign} and some other machinery like -@code{sb-ext:run-program}. It accepts a list of files and libraries, -and runs the linker on the files and libraries, creating an absolute -Unix object file which is then processed by @code{load-1-foreign}. +calling @code{load-shared-object}. -@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 +@include fun-sb-alien-unload-shared-object.texinfo -@node Foreign Function Calls, Step-By-Step Example of the Foreign Function Interface, Loading Unix Object Files, The Foreign Function Interface +@node Foreign Function Calls @comment node-name, next, previous, up @section Foreign Function Calls @@ -759,11 +721,11 @@ the only documentation. Users of a Lisp built with the * Calling Lisp From C:: @end menu -@node The alien-funcall Primitive, The define-alien-routine Macro, Foreign Function Calls, Foreign Function Calls +@node The alien-funcall Primitive @comment node-name, next, previous, up @subsection The @code{alien-funcall} Primitive -@defun sb-alien:alien-funcall @var{alien-function} &rest @var{arguments} +@defun @sbalien{alien-funcall} @var{alien-function} &rest @var{arguments} The @code{alien-funcall} function is the foreign function call primitive: @var{alien-function} is called with the supplied @@ -812,11 +774,11 @@ the @code{(* (struct foo))} objects filled in by the foreign call: result))) @end lisp -@node The define-alien-routine Macro, define-alien-routine Example, The alien-funcall Primitive, Foreign Function Calls +@node The define-alien-routine Macro @comment node-name, next, previous, up @subsection The @code{define-alien-routine} Macro -@defmac sb-alien:define-alien-routine @var{name} @var{result-type} &rest @var{arg-specifiers} +@defmac @sbalien{define-alien-routine} @var{name} @var{result-type} &rest @var{arg-specifiers} The @code{define-alien-routine} macro is a convenience for automatically generating Lisp interfaces to simple foreign functions. @@ -890,7 +852,7 @@ representations, avoiding consing.) @end defmac -@node define-alien-routine Example, Calling Lisp From C, The define-alien-routine Macro, Foreign Function Calls +@node define-alien-routine Example @comment node-name, next, previous, up @subsection @code{define-alien-routine} Example @@ -921,7 +883,7 @@ This can be described by the following call to The Lisp function @code{cfoo} will have two arguments (@var{str} and @var{a}) and two return values (@var{a} and @var{i}). -@node Calling Lisp From C, , define-alien-routine Example, Foreign Function Calls +@node Calling Lisp From C @comment node-name, next, previous, up @subsection Calling Lisp From C @@ -953,8 +915,7 @@ other ports it is implemented by turning off GC for the duration (so could be said to have a whole-world granularity). @item -Disable GC, using the @code{without-gcing} macro or @code{gc-off} -call. +Disable GC, using the @code{without-gcing} macro. @end enumerate @c -@node Step-By-Step Example of the Foreign Function Interface, , Foreign Function Calls, The Foreign Function Interface +@node Step-By-Step Example of the Foreign Function Interface @comment node-name, next, previous, up @section Step-By-Step Example of the Foreign Function Interface @@ -1129,7 +1090,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"; @@ -1188,20 +1149,19 @@ It is possible to call this C function from Lisp using the file @end lisp To execute the above example, it is necessary to compile the C -routine, e.g.: @samp{cc -c test.c} (In order to enable incremental -loading with some linkers, you may need to say @samp{cc -G 0 -c -test.c}) +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-foreign "test.o")}. 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")}