|Allegro CL version 9.0|
Unrevised from 8.2 to 9.0.
Arguments: lispname &key entry-point unconverted-entry-name arguments pass-types arg-checking prototype return-type language convert-symbol print address remember-address call-direct callback
This function is obsolete and maintained for backwards compatibility only. It has been replaced by the macro def-foreign-call. All new code should use that macro.
This function defines the calling convention which allows Lisp to call a foreign function correctly, passing arguments of the correct type, and interpreting the returned value correctly. lisp-name is the name (a symbol) by which lisp will refer to the foreign function.
If the entry point (either the value of entry-point or determined by other arguments as described below) does not exist, no error will be signaled when defforeign is called. Instead, the error will be signaled when the function defined by defforeign is called. This makes foreign functions more like Lisp functions -- if you define foo to call the undefined function bar, the error is signaled when foo is called, not when foo is defined.
The function defforeign creates a function identified by lisp-name, which passes its arguments through to the foreign code and returns the return-value of the foreign function to Lisp. The default passing convention (which can be overridden by using the pass-types keyword argument to defforeign) depends on the type of arguments and the language. For example, C normally expects its arguments to be passed by value, Fortran expects arguments to be passed by address.
t if it successfully defines the
foreign function. It returns
nil if it fails.
You can test whether or not an entry point exists with the function get-extern-code-address.
The following are the keyword arguments to defforeign.
|entry-point||foreign-name||This keyword's value foreign-name
is the name of the entry point as found in the loaded foreign
namespace. If no value is specified, the default depends on other
arguments. The determination of the entry-point need not happen
until the defforeign form is loaded
into (or evaluated within) Lisp and not when a file containing a
form is compiled into a fasl
file. If determination of the entry-point is delayed until a
fasl file is loaded, the
same fasl file can be used
on different platforms despite different conventions for naming
entry points (some platforms prepend a _, some append, and some do
not add _'s).
The entry-point name is determined as follows:
If entry-point is specified, it is used at compile time.
If entry-point is not specified but convert-symbol is,
where convert-symbol is the conversion function given in the keyword argument convert-symbol described below, is used as the entry point at compile time.
If neither entry-point nor convert-symbol are specified, unconverted-entry-name is stored at compile time and converted (with convert-to-lang) only when the resulting fasl file is loaded. This allows the same fasl files to be used on various platforms. unconverted-entry-name defaults to the symbol name of lisp-name.
Late conversion is the recommended behavior, so neither this argument nor convert-symbol should be specified. This argument and unconverted-entry-name should not both be specified.
|unconverted-entry-name||unconverted-entry-name||unconverted-entry-name should evaluate to a string. The method for determining the entry point name is given in the description of entry-point just above. If a value for this argument is specified, it is stored until the defforeign form defining the foreign function is loaded (or evaluated). At that time, unconverted-entry-name is converted with convert-to-lang to produce the entry-point name.|
|arguments||(argument-type+)||This specifies the types of arguments that will be
passed to the foreign function. Its value must be a list of valid
lisp types (e.g. the expressions integer, string, (simple-array
double-float), etc.), or t, which converts arguments according to
their type, whatever they are, or
The special type
|pass-types||pass-convention+||This keyword specifies the passing convention of
each argument. The choices are :by-address, meaning pass by
address (Fortran style) and :by-value, meaning pass by value (C
style). The default is the style of the language specified, so
users will rarely have to use this keyword. If the C code passes
arguments by address, however, then this keyword should be used
and its value should be a list of the same length as the argument
list with elements :by-value if the corresponding argument is
passed by value and :by-address if it is passed by address.
In addition to :by-value and :by-address, one can specify :normal and :non-array-by-address. :normal means to use the normal pass-type based on the value of the :language argument. :non-array-by-address means to pass the argument by address if the corresponding argument specified in the arguments list is not an array.
|arg-checking||t-or-nil||This argument defaults to t, in which case Lisp
will check that the arguments passed through to the foreign
function are of the types specified in
arguments. This argument is ignored if
arguments is t. This argument must be
|prototype||proto||This keyword is now effective on most
platforms. This keyword supports argument passing for machines
with ANSI C compilers which use function argument prototyping. C
functions written with ANSI C prototyping expect arguments to be
passed in a specific format. Before the advent of ANSI C
prototyping, one did not know what format the callee function
expected, so functions always passed in the largest value.
(ff:defforeign 'blarg :arguments (integer single-float single-float) :prototype (t t))
would say that the first two args are prototyped and the third is not.
To use defforeign on a function defined with a prototype, one must list the argument type with the argument keyword and have the prototype keyword argument true.
If one has argument checking enabled with the arg-checking keyword argument, then foreign function calling will be strict about getting the correct floating point type.
|return-type||return-type||The value of return-type must be one of the keywords
:void indicates no value is returned; :lisp indicates a Lisp value is returned
(normally used only if a C program returns a value accessed by the C routine
lisp_value()). The other keywords indicate values of the type named by the keyword. If the
value is :boolean, the function will return
When unspecified, this argument defaults to :integer.
|language||language-name||The language-name must be either of the keywords :c, for C, or :fortran, for Fortran. When unspecified, this argument defaults to :c. This argument is ignored if entry-point is specified.|
|t-or-nil||If t, information useful for debugging will be printed to *terminal-io*.
This argument defaults to
|convert-symbol||con-function||Note: specifying a value for this argument is not
recommended. See the description of
entry-point above for information on how Lisp
determines the entry-point name for a foreign function. If a value
for this argument is specified (and no value is specified for
unconverted-entry-name), the entry-point name
will be determined at compile time by applying the function which
is the value of this argument to lisp-name. The benefits of
determining the entry point only when the fasl file containing the
form is loaded (which allows for portability) is lost.
This keyword's value con-function is the name of the function that does the conversion of the Lisp name to an entry-point name. The function must take as arguments a symbol and the keyword :language, and must return a string recognizable to the operating system as an entry-point name.
|call-direct||t-or-nil||The default value of this argument is
A :call-direct foreign function will return the type specified by :return-type. In earlier releases, a double-float was sometimes returned when :return-type was :single-float. because the C routine returned a double and Lisp did not convert it. Starting in 4.3, Lisp converts the value returned by C if necessary.
|callback||callback||Because Allegro CL uses (on some platforms) the
:os-threads model of multiprocessing, it is not
possible to guarantee that Lisp code will not run while a foreign
function defined to Lisp with defforeign is running
(essentially what :callback nil did in earlier relases on
Unix). Therefore, whatever is specified for this argument,
||This argument allows for calling of C++ style member-methods. The value, if specified, must be an integer index into the virtual table of the C++ class. Symbolic index specifications are not directly supported.|
See ftype.htm for information on foreign types in Allegro CL and foreign-functions.htm for general information on foreign functions in Allegro CL.
Documentation for Allegro CL version 9.0. This page was not revised from the 8.2 page.
|Allegro CL version 9.0|
Unrevised from 8.2 to 9.0.