Windows only: A list value changes the image type created by
save-image
or
deliver
to
:dll
, which means that the saved image is a DLL file rather than an executable. The value of
:dll-exports
should be a list of strings naming the exports of the DLL. Each external name must be defined as a Lisp function by using
fli:define-foreign-callable
.
For example, the script below (with
lispworks-5-0-0-x86-win32.exe -init hello.lisp
) creates
hello.dll,
which can be run using "
rundll32 hello.dll,Hello
" from the command line. To see the dialog, you may need to click on the LispWorks splashscreen first.
-------------------- hello.lisp -------------------------
(in-package "CL-USER")
(load-all-patches)
;; The signature of this function is suitable for use with
;; rundll32.exe.
(fli:define-foreign-callable ("Hello"
:calling-convention :stdcall)
((hwnd w:hwnd)
(hinst w:hinstance)
(string :pointer)
(cmd-show :int))
(capi:display-message "Hello world"))
(save-image "hello"
:dll-exports '("Hello")
:environment nil)
(quit)
---------------------------------------------------------
You can use LoadLibrary from the main application to load the DLL and GetProcAddress to find the address of the external names. Lisp multiprocessing is started when the DLL is loaded, so any initialization operations can be done by adding process specifications to
mp:*initial-processes*
before creating the DLL.
For example, if you have a function like this:
(defun my-server ()
(let ((s (establish-a-socket)))
(loop (accept-connection s))))
(pushnew '("My server" () my-server) mp:*initial-processes*
:test 'equalp)
mp:*initial-processes*
is a list of lists. Each list is used by the system as a set of arguments to
mp:process-run-function
. During initializing multiprocessing, the system does this:
(dolist (x mp:*initial-processes*)
(apply 'mp:process-run-function x))