All Manuals > LispWorks Foreign Language Interface User Guide and Reference Manual > 5 Advanced Uses of the FLI


5.5 Using DLLs within the LispWorks FLI

In order to use functions defined in a dynamically linked library (DLL) within the LispWorks FLI, the functions need to be exported from the DLL.

5.5.1 Using C DLLs

You can export C functions in three ways:

  1. Use a __declspec(dllexport) declaration in the C file.
  2. In this case you should also make the functions use the cdecl calling convention, which removes another level of name mangling.

  3. Use an /export directive in the link command.
  4. Use a .def file.

An example of method 3 follows. Let us assume you have the following C code in a file called example.c.

int _stdcall MultiplyMain(void *hinstDll,unsigned long 
                          dwReason,void *reserved)
int multiply (int i1, int i2)
 { int result;
  result = i1 * i2 * 500;
  return result;

Then you can create a DLL by, for example, using a 32 bit C compiler such as lcc.

lcc -O -g2 example.c
lcclnk.exe -dll -entry MultiplyMain example.obj 
example.def -subsystem

You now need to create a multiply.def file that contains the following line

exports multiply=multiply

to export the function multiply as the symbol multiply. If you only include the line "exports multiply" then the name of the external symbol is likely to be "_multiply" or "_multiply@8" depending on whether the function is compiled as __cdecl or __stdcall. The addition of the "= multiply" overrides the internal function name with the new name.

If you run Windows then you can view the list of exported symbols from a given DLL by selecting the DLL from an explorer, then right clicking on it and selecting QuickView. This brings up some text about the DLL.

Finally, you should use the LispWorks FLI to define your C function in your Lisp code. This definition should look something like:

(fli:define-foreign-function (multiply "multiply")
     ((x :int)
      (y :int))
   :result-type int
   :module :my-dll
   :calling-convention :cdecl)

Note that the define-foreign-function also includes a :calling-convention keyword to specify that the function we are interfacing to is defined as using the __cdecl calling convention. Testing whether a function is defined

Having loaded your DLLs (with register-module) you may wish to test whether certain functions are now available.

To detect when a C function name is defined, call

(not (fli:null-pointer-p
      (fli:make-pointer :symbol-name name
                        :errorp nil)))

You can also return a list of unresolved foreign symbol names by calling module-unresolved-symbols.

5.5.2 Using C++ DLLs

You must make the exported names match the FLI definitions. To do this:

Note: watch out for the calling convention of the exported function, which must match the :calling-convention in the FLI definitions.

LispWorks Foreign Language Interface User Guide and Reference Manual - 16 Feb 2015