define-foreign-function name ({ arg }*) &key lambda-list documentation result-type language no-check calling-convention module => lisp-name
name ::= lisp-name | ( lisp-name foreign-symbol [ encoding ]) | ( lisp-name foreign-string [ encoding ])
encoding ::= :source | :object | :lisp | :dbcs
Either a symbol naming the defined Lisp function, or a list containing the name of the Lisp function, the corresponding foreign function name and optionally an encoding option.
A symbol naming the defined Lisp function.
A symbol naming the foreign function.
A string containing the name of the foreign function.
An option controlling how the Lisp function name is translated into the function name in the foreign object code. The encoding option can be one of the following:
:source
tells LispWorks that the string
foreign-string
or the symbol
foreign-symbol
is the name of the function in the foreign source code. This is the default value of
encoding
.
:object
tells LispWorks that the string
foreign-string
or the symbol
foreign-symbol
is the literal name of the function in the foreign object code.
:lisp
tells LispWorks that the symbol
foreign-symbol
is a Lisp symbol and must be translated and encoded.
:dbcs
adds a suffix onto the function name which will automatically change depending on whether Lisp image is started up in the Windows NT or Windows 95 operating system. The suffix is "
A
" for Windows 95 and "
W
" for Windows NT.
Either an argument name, a list containing an argument name and a type, or a list of the form
(:constant
value
value-type
)
. Lisp arguments may take any name, but the types must be accurately specified and listed in the same order as in the foreign function, unless otherwise specified using
lambda-list
.
If only an
arg-name
is supplied, then
define-foreign-function
assumes that it is of type
:int
.
If
arg
is of the form
(:constant
value
value-type
)
then
value
is always passed through to the foreign code.
The lambda list to be used for the defined Lisp function. If this is not specified, the lambda list is generated from the list of
arg
s. The
lambda-list
keyword allows you to define the order in which the Lisp function takes its arguments to be different from the order in which the foreign function takes them, and to use standard lambda list keywords such as
&optional
. The default value of
lambda-list
is
nil
.
A documentation string for the foreign function.
The type of the foreign function's return value.
The name of the keyword argument that is added to the lambda-list of the Lisp function when the result-type is an aggregate type.
The language in which the foreign source code is written. The default is
:c
.
If
nil
, the types of the arguments provided when the Lisp function is called are compared with the expected types and an error is raised if they do not match. Setting
no-check
to
t
overrides this check.
If the compilation safety level is set to 0 then
no-check
is automatically set to
t
. The default value for
no-check
is
nil
.
Specifies the calling convention used.
:stdcall
is the calling convention used to call Win32 API functions and matches the C declarator
"__stdcall"
. This is the default on Windows.
:cdecl
is the default calling convention for C/C++ programs and matches the C declarator
"__cdecl"
. This is the default on Unix/Linux. There is no calling convention issue on Macintosh.
Specifies the module in which the foreign symbol is defined. If it is the name of a module registered using
register-module then that module is used to look up the symbol. If the name of the module is a string then that module is automatically registered and used to look up the symbol.
Note: This argument is accepted only in LispWorks for Windows and LispWorks for Linux.
The macro
define-foreign-function
defines a Lisp function which acts as an interface to a foreign language function, for example a C function. When the Lisp function is called its arguments are converted to the appropriate foreign representation before being passed to the specified foreign function. Once the foreign function exits, any return values are converted back from the foreign format into a Lisp format.
The number and types of the Lisp function's arguments must be given, and optionally the type of the return value may be specified too. The order in which the Lisp function takes its arguments can be different from the order expected by the foreign function, using the lambda-list argument.
The
:reference
,
:reference-pass
and
:reference-return
types are useful with
define-foreign-function
. It is fairly common for a C function to return a value by setting the contents of an argument passed by reference (that is, as a pointer). This can be handled conveniently by using the
:reference-return
type, which dynamically allocates memory for the return value and passes a pointer to the C function. On return, the pointer is dereferenced and the value is returned as an extra multiple value from the Lisp function.
The
:reference-pass
type can be used to automatically construct an extra level of pointer for an argument. No extra results are returned.
The
:reference
type is like
:reference-return
but allows the initial value of the reference argument to be set.
When
result-type
is a aggregate type, an additional keyword argument is placed in the lambda-list of the Lisp function. This keyword is named after the
result-pointer
argument or is called
:result-pointer
if unspecifed. When calling the Lisp function, a foreign pointer must be supplied as the value of this keyword argument, pointing to an object of type
result-type
. The result of the foreign call is written into this object and the foreign pointer is returned as the primary value from the Lisp function. This allows the caller to maintain control over the lifetime of this object (in C this would typically be stored in a local variable).
A simple example of the use of
define-foreign-function
is given in Defining an FLI function. More detailed examples are given in Advanced Uses of the FLI.
Here is an example using the
:reference-return
type.
int cfloor(int x, int y, int *remainder)
{
int quotient = x/y;
*remainder = x - y*quotient;
return quotient;
}
__declspec(dllexport) int __cdecl cfloor(int x, int y, int *remainder)
{
int quotient = x/y;
*remainder = x - y*quotient;
return quotient;
}
In this foreign function definition the main result is the quotient and the second return value is the remainder:
(fli:define-foreign-function cfloor
((x :int)
(y :int)
(rem (:reference-return :int)))
:result-type :int)
(cfloor 11 5 t)
=>
2,1