.DLL
and .so
filesThis section discusses the functionality of the (autoload) library
shlib.pl
, providing an interface to shared libraries.
Currently it supports MS-Windows DLL (.DLL
) libraries and
Unix
.so
(shared object) files.
foreign
, which refers to
the directories <plhome>/lib/<arch>
and
<plhome>/lib
, in this order.
If the library can be loaded, the function called Entry will be called without arguments. The return value of the function is ignored.
The Entry function will normally call PL_register_foreign() to declare functions in the library as foreign predicates.
Figure 5 connects a Windows message-box using a foreign function. This example was tested using Windows NT and Microsoft Visual C++ 2.0.
#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() { PL_register_foreign("say_hello", 1, pl_say_hello, 0); } |
Below is an outline of the files structure required for statically
linking SWI-Prolog with foreign extensions. \ldots/pl
refers to the SWI-Prolog home directory (see feature/2). <arch>
refers to the architecture identifier that may be obtained using feature/2.
... /pl/runtime/<arch>/libpl.a | SWI-Library |
\ldots/pl/include/SWI-Prolog.h | Include file |
\ldots/pl/include/SWI-Stream.h | Stream I/O include file |
\ldots/pl/include/SWI-Exports | Export declarations (AIX only) |
\ldots/pl/include/stub.c | Extension stub |
The definition of the foreign predicates is the same as for dynamic
linking. Unlike with dynamic linking however, there is no initialisation
function. Instead, the file \ldots/pl/include/stub.c
may be
copied to your project and modified to define the foreign extensions.
Below is stub.c, modified to link the lowercase example described later
in this chapter:
/* Copyright (c) 1991 Jan Wielemaker. All rights reserved. jan@swi.psy.uva.nl Purpose: Skeleton for extensions */ #include <stdio.h> #include <SWI-Prolog.h> extern foreign_t pl_lowercase(term, term); PL_extension predicates[] = { /*{ "name", arity, function, PL_FA_<flags> },*/ { "lowercase", 2 pl_lowercase, 0 }, { NULL, 0, NULL, 0 } /* terminating line */ }; int main(int argc, char **argv) { PL_register_extensions(predicates); if ( !PL_initialise(argc, argv) ) PL_halt(1); PL_install_readline(); /* delete if not required */ PL_halt(PL_toplevel() ? 0 : 1); } |
Now, a new executable may be created by compiling this file and linking it to libpl.a from the runtime directory and the libraries required by both the extensions and the SWI-Prolog kernel. This may be done by hand, or using the plld utility described in secrefplld.
The predicates below are considered obsolete. They are briefly
described here for compatibility purposes. New code should use the
predicates from the library(shlib)
.
.o
' extension is used rather than `.pl
'.
Entry defines the entry point of the resulting executable. The entry point will be called by Prolog to install the foreign predicates.