12.2.3 library(shlib): Utility library for loading foreign objects (DLLs, shared objects)
This section discusses the functionality of the (autoload)
library(shlib)
, providing an interface to manage shared
libraries. We describe the procedure for using a foreign resource (DLL
in Windows and shared object in Unix) called mylib
.
First, one must assemble the resource and make it compatible to
SWI-Prolog. The details for this vary between platforms. The swipl-ld(1)
utility can be used to deal with this in a portable manner. The typical
commandline is:
swipl-ld -o mylib file.{c,o,cc,C} ...
Make sure that one of the files provides a global function
install_mylib()
that initialises the module using calls to
PL_register_foreign(). Here is a simple example file mylib.c, which
creates a Windows MessageBox:
#include <windows.h> #include <SWI-Prolog.h> static foreign_t pl_say_hello(term_t to) { char *a; if ( PL_get_atom_chars(to, &a) ) { MessageBox(NULL, a, "DLL test", MB_OK|MB_TASKMODAL); PL_succeed; } PL_fail; } install_t install_mylib() { PL_register_foreign("say_hello", 1, pl_say_hello, 0); }
Now write a file mylib.pl
:
:- module(mylib, [ say_hello/1 ]). :- use_foreign_library(foreign(mylib)).
The file mylib.pl
can be loaded as a normal Prolog file
and provides the predicate defined in C.
- [det]use_foreign_library(+FileSpec)
- [det]use_foreign_library(+FileSpec, +Entry:atom)
- Load and install a foreign library as load_foreign_library/1,2
and register the installation using initialization/2
with the option
now
. This is similar to using::- initialization(load_foreign_library(foreign(mylib))).
but using the initialization/1 wrapper causes the library to be loaded after loading of the file in which it appears is completed, while use_foreign_library/1 loads the library immediately. I.e. the difference is only relevant if the remainder of the file uses functionality of the C-library.
As of SWI-Prolog 8.1.22, use_foreign_library/1,2 is in provided as a built-in predicate that, if necessary, loads
library(shlib)
. This implies that these directives can be used without explicitly loadinglibrary(shlib)
or relying on demand loading. - [semidet,multifile]qsave:compat_arch(Arch1, Arch2)
- User definable hook to establish if Arch1 is compatible with Arch2
when running a shared object. It is used in saved states produced by
qsave_program/2
to determine which shared object to load at runtime.
- See also
foreign
option in qsave_program/2 for more information.
- [det]load_foreign_library(:FileSpec)
- [det]load_foreign_library(:FileSpec, +Entry:atom)
- Load a shared object or DLL. After loading the Entry
function is called without arguments. The default entry function is
composed from =install_=, followed by the file base-name. E.g., the
load-call below calls the function
install_mylib()
. If the platform prefixes extern functions with =_=, this prefix is added before calling.... load_foreign_library(foreign(mylib)), ...
FileSpec is a specification for absolute_file_name/3. If searching the file fails, the plain name is passed to the OS to try the default method of the OS for locating foreign objects. The default definition of file_search_path/2 searches <prolog home>/lib/<arch> on Unix and <prolog home>/bin on Windows. - See also
- use_foreign_library/1,2 are intended for use in directives.
- [det]unload_foreign_library(+FileSpec)
- [det]unload_foreign_library(+FileSpec, +Exit:atom)
- Unload a shared object or DLL. After calling the Exit function, the shared object is removed from the process. The default exit function is composed from =uninstall_=, followed by the file base-name.
- current_foreign_library(?File, ?Public)
- Query currently loaded shared libraries.
- reload_foreign_libraries
- Reload all foreign libraries loaded (after restore of a state created using qsave_program/2.
- [det]win_add_dll_directory(+AbsDir)
- Add AbsDir to the directories where dependent DLLs are
searched on Windows systems.
- Errors
domain_error(operating_system, windows)
if the current OS is not Windows.