$Revision: 5.0.2.4 $
Package: FOREIGN-FUNCTIONS
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 ff: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 ff: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.
ff:defforeign returns 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 ff:get-extern-code-address.
The following are the keyword arguments to ff:defforeign.
Argument | Value | Description |
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 defforeign 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 ff: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 above 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 ff: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 nil , which means no arguments.
When unspecified, this argument defaults to t. 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 nil
if call-direct is specified t (otherwise the call will not be
inlined). |
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. The
default is For example:
would say that the first two args are prototyped and the third is not. To use ff:defforeign on a function defined with a prototype, one must
list the argument type with the argument keyword and have the prototype
keyword argument non- 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 nil . |
|
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 entry-point or 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 defforeign 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 nil . If this
value is t, then the compiler will attempt to inline calls to the foreign function being
defined by this call to ff:defforeign. If the value of :call-direct is t then
the :arguments keyword argument must be a list of arguments rather than t and
arg-checking must be nil (otherwise :call-direct's value will be
ignored). :callback may be t or nil but if it is t, extra code
must be included to allow for the callback so the inlined call is slower.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 5.0 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, t is the value used. See the release-heap keyword argument
of def-foreign-call. |
method-index | nil (the default) or an index into C++ table, as
described at right. |
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 foreign_functions.htm for general information on foreign functions in Allegro CL. See ftype.htm for information on foreign types.
The general documentation description is in introduction.htm. The index is in index.htm.
Copyright (C) 1998-1999, Franz Inc., Berkeley, CA. All Rights Reserved.