A foreign resource is a set of C functions, defined in one or more files, installed as an atomic operation. The name of a foreign resource, the resource name, is an atom, which should uniquely identify the resource. Thus, two foreign resources with the same name cannot be installed at the same time, even if they correspond to different files.
The resource name of a foreign resource is derived from its file
name by deleting any leading path and the suffix. Therefore the resource
name is not the same as the absolute file name. For example, the
resource name of both ~john/foo/bar.so and
~ringo/blip/bar.so is bar
. If
load_foreign_resource('~john/foo/bar')
has been done
~john/foo/bar.so will be unloaded if either
load_foreign_resource('~john/foo/bar')
or
load_foreign_resource('~ringo/blip/bar')
is subsequently called.
It is recommended that a resource name be all lowercase, starting with ‘a’ to ‘z’ followed by a sequence consisting of ‘a’ to ‘z’, underscore (‘_’), and digits. The resource name is used to construct the file name containing the foreign resource.
For each foreign resource, a foreign_resource/2
fact
is used to declare the interfaced functions. For each of these
functions, a foreign/[2,3]
fact is used to specify
conversions between predicate arguments and C-types. These
conversion declarations are used for creating the necessary interface
between Prolog and C.
The functions making up the foreign resource, the automatically generated glue code, and any libraries, are compiled and linked, using the splfr tool (see The Foreign Resource Linker), to form a linked foreign resource. A linked foreign resource can be either static or dynamic. A static resource is simply a relocatable object file containing the foreign code. A dynamic resource is a shared library (‘.so’ under most UNIX dialects, ‘.dll’ under Windows), which is loaded into the Prolog executable at runtime.
Foreign resources can be linked into the Prolog executable either when the executable is built (pre-linked), or at runtime. Pre-linking can only be done using static resources. Runtime-linking can only be done using dynamic resources. Dynamic resources can also be unlinked.
In all cases, the declared predicates are installed by the
built-in predicate load_foreign_resource/1
.
If the resource was pre-linked, only the predicate
names are bound; otherwise, runtime-linking is attempted (using
dlopen()
, LoadLibrary()
, or similar).