The following example shows how to use the FLI to call a C function. The function to interface with,
FahrenheitToCelsius, takes one integer as its argument (the temperature in Fahrenheit) and returns the result as a single float (the temperature in Celsius).
The example consists of three stages: defining a foreign language interface to the C function, loading the foreign code into the Lisp image, and calling the C function to obtain the results.
The FLI provides the macro define-foreign-function for creating interfaces to foreign functions. It takes the name of the function you wish to interface to, the argument types the function accepts, and the result type the function returns.
float FahrenheitToCelsius( int );
The first argument to define-foreign-function declares that
fahrenheit-to-celsius is the name of the Lisp function that is generated to interface with the C function
:source keyword is a directive to define-foreign-function that
FahrenheitToCelsius is the name of the C function as seen in the source files. On some platforms the actual symbol name available in the foreign object file we are interfacing with could include character prefixes such as "
." and "
_", and so the
:source keyword encoding allows you to write cross-platform portable foreign language interfaces.
The second argument to define-foreign-function,
((fahrenheit :int)), is the argument list for the foreign function. In this case, only one argument is required. The first part of each argument descriptor is the lambda argument name. The rest of the argument describes the type of argument we are trying to interface to and how the conversion from Lisp to C is performed. In this case the foreign type
:int specifies that we are interfacing between a Lisp integer and a C type "int".
:result-type keyword tells us that the conversion required between the C function and Lisp uses the foreign type
:float. This tells Lisp that C will return a result of type "float", which needs to be converted to a Lisp single-float.
The final keyword argument,
:language, specifies which language the foreign function was written in. In this case the example uses ANSI C. This keyword determines how single-floating point values are passed to and returned from C functions as described for define-foreign-function.
LispWorks for UNIX can either load object files (usually suffixed with "
.o") directly into the Lisp image, extract any required object files from the available archive libraries (usually suffixed with "
.a"), or load in shared libraries (usually suffixed with "
On all platforms the function register-module is the main LispWorks interface to DLL files. It is used to specify which DLLs are looked up when searching for foreign symbols. Here are example forms to register a connection to a DLL.
Note: LispWorks for UNIX also provides the loader function
link-load:read-foreign-modules familiar to users of LispWorks 4.3 and earlier. However, this is now deprecated in favor of register-module.
Note: It is also possible to embed a DLL in the Lisp image. See Incorporating a foreign module into a LispWorks image.
Calling the foreign code is the simplest part of using the FLI. The interface to the C function, defined using define-foreign-function, is called like any other Lisp function. In our example, the
fahrenheit-to-celsius function takes the temperature in Fahrenheit as its only argument, and returns the temperature in Celsius.
LispWorks Foreign Language Interface User Guide and Reference Manual - 29 Sep 2017