4.4.4 Further example

This example builds a dynamic library which in principle could be loaded by any application and called to calculate square numbers.

For illustrative purposes, we show how to load the dynamic library into the LispWorks development image. This illustrates some platform-specific initialization. Then we use the library, ensure it exits cleanly, and finally delete the dynamic library file.

Note that on Linux/Macintosh/FreeBSD, to deliver a dynamic library, the build machine must have a C compiler installed.

For convenience the code is presented without external files. To run it, copy each form in turn and enter it at the Listener prompt.

Define a path for the dynamic library:

(defvar *dynamic-library-path*

(merge-pathnames (make-pathname :name "CalculateSquareExample"

:type scm::*object-file-suffix*)

(get-temp-directory)))

Define a function to create the dynamic library:

(defun save-dynamic-library ()

(let* ((file (make-temp-file t "lisp"))

(ns (namestring file)))

(format file

"

(fli:define-foreign-callable (calculate-square :result-type :int)

((arg :int))

(* arg arg))

(deliver nil ~s 5 :dll-exports '(\"calculate_square\"))"

(namestring *dynamic-library-path*))

(close file)

(sys:call-system-showing-output (list (lisp-image-name)

"-build"

ns ))

(delete-file file nil)))

Create the dynamic library:

(save-dynamic-library)

Define functions to use the dynamic library:

(fli:define-foreign-function (my-quit-lispworks "QuitLispWorks")

((force :int)

(milli-timeout :int))

:result-type :int

;; specifying :module ensures the foreign function finds

;; the function in our module

:module 'my-dynamic-library)

(fli:define-foreign-function (my-init-lispworks "InitLispWorks")

((milli-timeout :int)

(base-address (:pointer-integer :int))

(reserve-size (:pointer-integer :int)) ; really size_t

)

:result-type :int

:module 'my-dynamic-library)

(fli:define-foreign-function calculate-square

((arg :int))

:result-type :int

:module 'my-dynamic-library)

Define a function to load the dynamic library, use it, and then unload it: