- Documentation
- Reference manual
- Foreign Language Interface
- The Foreign Include File
- Argument Passing and Control
- Atoms and functors
- Analysing Terms via the Foreign Interface
- Constructing Terms
- Unifying data
- Convenient functions to generate Prolog exceptions
- Serializing and deserializing Prolog terms
- BLOBS: Using atoms to store arbitrary binary data
- Exchanging GMP numbers
- Calling Prolog from C
- Discarding Data
- String buffering
- Foreign Code and Modules
- Prolog exceptions in foreign code
- Catching Signals (Software Interrupts)
- Miscellaneous
- Errors and warnings
- Environment Control from Foreign Code
- Querying Prolog
- Registering Foreign Predicates
- Foreign Code Hooks
- Storing foreign data
- Embedding SWI-Prolog in other applications
- The Foreign Include File
- Foreign Language Interface
- Packages
- Reference manual
- int PL_is_blob(term_t t, PL_blob_t **type)
- Succeeds if t refers to a blob, in which case type is filled with the type of the blob.
- int PL_unify_blob(term_t t, void *blob, size_t len, PL_blob_t *type)
- Unify t to a blob constructed from the given data and
associated with the given type. This performs the following steps:
- If the type has
PL_BLOB_UNIQUE
set, search the blob database for a blob of the same type with the same content. If found, unify t with the existing handle. - If not found or
PL_BLOB_UNIQUE
is not set, create a new blob handle. IfPL_BLOB_NOCOPY
is set, associate it to the given memory; else, copy the memory to a new area owned by the blob. Call the acquire() function of the type. - Unify t with the existing or new handle. This succeeds if t is already bound to the existing blob handle. If t is a variable, it succeeds if sufficient resources are available to perform the unification; if t is bound to something else, this fails.
It is possible that a blob referencing critial resources is created after which the unification fails. Typically these resources are eventually reclaimed because the new blob is not referenced and reclaimed by the atom garbage collector. As described with the release(f)unction, it can be desirable to reclaim the critical resources after the failing PL_unify_blob() call.
- If the type has
- int PL_put_blob(term_t t, void *blob, size_t len, PL_blob_t *type)
- Store the described blob in t. The return value indicates
whether a new blob was allocated (
FALSE
) or the blob is a reference to an existing blob (TRUE
). Reporting new/existing can be used to deal with external objects having their own reference counts. If the return isTRUE
this reference count must be incremented, and it must be decremented on blob destruction callback. See also PL_put_atom_nchars(). - int PL_get_blob(term_t t, void **blob, size_t *len, PL_blob_t **type)
- If t holds a blob or atom, get the data and type and return
TRUE
. Otherwise returnFALSE
. Each result pointer may beNULL
, in which case the requested information is ignored. - void * PL_blob_data(atom_t a, size_t *len, PL_blob_t **type)
-
Get the data and type associated to a blob. This function is mainly used from the callback functions described in section 12.4.9.1. Note that if the release() hook is called from PL_cleanup(), blobs are releases regardless of whether or not they are referenced and the order in which blobs are released is undefined (the order depends on the ordering in the atom hash table). PL_blob_data() may be called safely on a blob that has already been released. If this happens during PL_cleanup() the return value is guaranteed to be
NULL
. During normal execution it may return the content of a newly allocated blob that reused the released handle.
12.4.10 Exchanging GMP numbers
If SWI-Prolog is linked with the GNU Multiple Precision Arithmetic
Library (GMP, used by default), the foreign interface provides functions
for exchanging numeric values to GMP types. To access these functions
the header <gmp.h>
must be included before
<SWI-Prolog.h>
. Foreign code using GMP linked to
SWI-Prolog asks for some considerations.
- SWI-Prolog normally rebinds the GMP allocation functions using
mp_set_memory_functions(). This means SWI-Prolog must be initialised
before the foreign code touches any GMP function. You can call
PL_action(PL_GMP_SET_ALLOC_FUNCTIONS, TRUE)
to force Prolog's GMP initialization without doing the rest of the Prolog initialization. If you do not want Prolog rebinding the GMP allocation, callPL_action(PL_GMP_SET_ALLOC_FUNCTIONS, FALSE)
before initializing Prolog. - On Windows, each DLL has its own memory pool. To make exchange of GMP numbers between Prolog and foreign code possible you must either let Prolog rebind the allocation functions (default) or you must recompile SWI-Prolog to link to a DLL version of the GMP library.
Here is an example exploiting the function mpz_nextprime():
#include <gmp.h> #include <SWI-Prolog.h> static foreign_t next_prime(term_t n, term_t prime) { mpz_t mpz; int rc; mpz_init(mpz); if ( PL_get_mpz(n, mpz) ) { mpz_nextprime(mpz, mpz); rc = PL_unify_mpz(prime, mpz); } else rc = FALSE; mpz_clear(mpz); return rc; } install_t install() { PL_register_foreign("next_prime", 2, next_prime, 0); }
- int PL_get_mpz(term_t t, mpz_t mpz)
- If t represents an integer, mpz is filled with the
value and the function returns
TRUE
. Otherwise mpz is untouched and the function returnsFALSE
. Note that mpz must have been initialised before calling this function and must be cleared using mpz_clear() to reclaim any storage associated with it. - int PL_get_mpq(term_t t, mpq_t mpq)
- If t is an integer or rational number (term
rdiv/2
), mpq is filled with the normalised rational number and the function returnsTRUE
. Otherwise mpq is untouched and the function returnsFALSE
. Note that mpq must have been initialised before calling this function and must be cleared using mpq_clear() to reclaim any storage associated with it. - int PL_unify_mpz(term_t t, mpz_t mpz)
- Unify t with the integer value represented by mpz
and return
TRUE
on success. The mpz argument is not changed. - int PL_unify_mpq(term_t t, mpq_t mpq)
- Unify t with a rational number represented by mpq
and return
TRUE
on success. Note that t is unified with an integer if the denominator is 1. The mpq argument is not changed.
12.4.11 Calling Prolog from C
The Prolog engine can be called from C. There are two interfaces for this. For the first, a term is created that could be used as an argument to call/1, and then PL_call() is used to call Prolog. This system is simple, but does not allow to inspect the different answers to a non-deterministic goal and is relatively slow as the runtime system needs to find the predicate. The other interface is based on PL_open_query(), PL_next_solution(), and PL_cut_query() or PL_close_query(). This mechanism is more powerful, but also more complicated to use.
12.4.11.1 Predicate references
This section discusses the functions used to communicate about
predicates. Though a Prolog predicate may be defined or not, redefined,
etc., a Prolog predicate has a handle that is neither destroyed nor
moved. This handle is known by the type predicate_t
.
- predicate_t PL_pred(functor_t f, module_t m)
- Return a handle to a predicate for the specified name/arity in the given
module. If the module argument m is
NULL
, the current context module is used. If the target predicate does not exist a handle to a new undefined predicate is returned. The predicate may fail, returning(predicate_t)0
after setting a resource exception, if the target module has a limit on theprogram_space
, see set_module/1. Currently aborts the process with a fatal error when out of memory. Future versions may raise a resource exception and return(predicate_t)0
. - predicate_t PL_predicate(const char *name, int arity, const char* module)
- Same as PL_pred(),
but provides a more convenient interface to the C programmer. If the
module argument module is
NULL
, the current context module is used. Thepredicate_t
handle may be stored as global data and reused for future queries219PL_predicate() involves 5 hash lookups (two to get the atoms, one to get the module, one to get the functor and the final one to get the predicate associated with the functor in the module) as illustrated below.static predicate_t p = 0; ... if ( !p ) p = PL_predicate("is_a", 2, "database");
Note that PL_cleanup() invalidates the predicate handle. Foreign libraries that use the above mechanism must implement the module uninstall() function to clear the
predicate_t
global variable. - void PL_predicate_info(predicate_t p, atom_t *n, size_t *a, module_t *m)
- Return information on the predicate p. The name is stored
over
n, the arity over a, while m receives
the definition module. Note that the latter need not be the same as
specified with
PL_predicate().
If the predicate is imported into the module given to
PL_predicate(),
this function will return the module where the predicate is defined. Any
of the arguments n, a and m can be
NULL
.
12.4.11.2 Initiating a query from C
This section discusses the functions for creating and manipulating queries from C. Note that a foreign context can have at most one active query. This implies t