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. This can be done in three ways:
__declspec(ddlexport)
declaration in the C file. stdcall
calling convention, which removes another level of name mangling. /export
directive in the link command. .def
file. An example of method 3 follows. Let us assume you have the following C code in a file calledexample.c
.
int _stdcall MultiplyMain(void *hinstDll,unsigned long dwReason,void *reserved) { return(1); } 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 windows
You now need to create amultiply.def
file that contains the following line
exports multiply=multiply
to export the functionmultiply
as the symbolmultiply
. 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 either Windows 95 or Windows NT4, 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 thedefine-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.