- 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
representation_error(resource)
. See representation_error/1.type_error(expected, culprit)
. See type_error/2.domain_error(expected, culprit)
. See domain_error/2.existence_error(type, culprit)
. See type_error/2.permission_error(operation, type, culprit)
. See
permission_error/3.resource_error(resource)
. See resource_error/1.syntax_error(message)
. If arg is not NULL
,
add information about the current position of the input stream.
12.4.7 Foreign language wrapper support functions
In addition to the functions described in
section 12.4.3.2,
there is a family of functions that is used for automatic generation of
wrapper functions, for example using the Prolog library library(qpforeign)
that provides a Quintus/SICStus compatible foreign language interface.
The PL_cvt_i_*() family of functions is suitable for use with a
_Generic
selector or C++ overloading.217_Generic
needs to take into account that there's no bool
type in C
but there is in C++. An overloaded integer() method is provided in the
C++ interface.
Note that the documentation on this API is incomplete. Also note that many of these functions are equivalent to the PL_get_*_ex() functions described in section 12.4.6.
- int PL_cvt_i_bool(term_t p, int *c)
- Equivalent to PL_get_bool_ex().
Note that the pointer is to an
int
because C has nobool
type. The return value is either0
or1
. - int PL_cvt_i_char(term_t p, char *c)
- int PL_cvt_i_schar(term_t p, signed char *c)
- int PL_cvt_i_uchar(term_t p, unsigned char *c)
- int PL_cvt_i_short(term_t p, short *s)
- int PL_cvt_i_ushort(term_t p, unsigned short *s)
- int PL_cvt_i_int(term_t p, int *c)
- int PL_cvt_i_uint(term_t p, unsigned int *c)
- int PL_cvt_i_long(term_t p, long *c)
- int PL_cvt_i_ulong(term_t p, unsigned long *c)
- int PL_cvt_i_llong(term_t p, long long *c)
- int PL_cvt_i_ullong(term_t p, unsigned long long *c)
- int PL_cvt_i_int32(term_t p, int32_t *c)
- int PL_cvt_i_uint32(term_t p, uint32_t *c)
- int PL_cvt_i_int64(term_t p, int64_t *c)
- int PL_cvt_i_uint64(term_t p, uint64_t *c)
- int PL_cvt_i_size_t(term_t p, size_t *c)
- Convert a Prolog integer into a C integer of the specified size.
Generate an exception and return
FALSE
if the conversion is impossible because the Prolog term is not an integer or the C type cannot represent the value of the Prolog integer.
12.4.8 Serializing and deserializing Prolog terms
- int PL_put_term_from_chars(term_t t, int flags, size_t len, const char *s)
- Parse the text from the C-string s holding len
bytes and put the resulting term in t. len can be
(size_t)-1
, assuming a 0-terminated string. The flags argument controls the encoding and is currently one ofREP_UTF8
(string is UTF8 encoded),REP_MB
(string is encoded in the current locale) or 0 (string is encoded in ISO latin 1). The string may, but is not required, to be closed by a full stop (.).If parsing produces an exception the behaviour depends on the
CVT_EXCEPTION
flag. If present, the exception is propagated into the environment. Otherwise, the exception is placed in t and the return value isFALSE
.218TheCVT_EXCEPTION
was added in version 8.3.12.
12.4.9 BLOBS: Using atoms to store arbitrary binary data
SWI-Prolog atoms as well as strings can represent arbitrary binary data of arbitrary length. This facility is attractive for storing foreign data such as images in an atom. An atom is a unique handle to this data and the atom garbage collector is able to destroy atoms that are no longer referenced by the Prolog engine. This property of atoms makes them attractive as a handle to foreign resources, such as Java atoms, Microsoft's COM objects, etc., providing safe combined garbage collection.
To exploit these features safely and in an organised manner, the SWI-Prolog foreign interface allows creating‘atoms' with additional type information. The type is represented by a structure holding C function pointers that tell Prolog how to handle releasing the atom, writing it, sorting it, etc. Two atoms created with different types can represent the same sequence of bytes. Atoms are first ordered on the rank number of the type and then on the result of the compare() function. Rank numbers are assigned when the type is registered. This implies that the results of inequality comparisons between blobs of different types is undefined and can change if the program is run twice (the ordering within a blob type will not change, of course).
While the blob is alive, neither its handle nor the location of the
contents (see PL_blob_data())
change. If the blob's type has the
PL_BLOB_UNIQUE
feature, the content of the blob must remain
unmodified. Blobs are only reclaimed by the atom garbage
collector. In this case the atom garbage collector calls the
release(f)unction
associated with the blob type and reclaims the memory allocated for the
content unless this is owned by the creator of the blob indicated by the PL_BLOB_NOCOPY
flag. After an
atom_t
value is reclaimed by the atom garbage collector,
the value may be reused for allocating a new blob or atom.
If foreign code stores the atom_t
handle in some
permanent location it must make sure the handle is registered
to prevent it from being garbage collected. If the handle is obtained
from a
term_t
object it is not registered because it is
protected by the term_t
object. This applies to e.g.,
PL_get_atom().
Functions that create a handle from data such as
PL_new_atom()
return a registered handle to prevent the asynchronous atom garbage
collector from reclaiming it immediately. Note that many of the API
functions create an atom or blob handle and use this to fill a
term_t
object, e.g., PL_unify_blob(), PL_unify_chars(),
etc. In this scenario the handle is protected by the term_t
object. Registering and unregistering atom_t
handles is
done by
PL_register_atom()
and PL_unregister_atom().
Note that during program shutdown using PL_cleanup(), all atoms and blobs are reclaimed as described above. These objects are reclaimed regardless of their registration count. The order in which the atoms or blobs are reclaimed under PL_cleanup() is undefined. However, when these objects are reclaimed using garbage_collect_atoms/0, registration counts are taken into account.
12.4.9.1 Defining a BLOB type
The type PL_blob_t
represents a structure with the
layout displayed below. The structure contains additional fields at the
... for internal bookkeeping as well as future extensions.
typedef struct PL_blob_t { uintptr_t magic; /* PL_BLOB_MAGIC */ uintptr_t flags; /* Bitwise or of PL_BLOB_* */ const char * name; /* name of the type */ int (*release)(atom_t a); int (*compare)(atom_t a, atom_t b); int (*write)(IOSTREAM *s, atom_t a, int flags); void (*acquire)(atom_t a); int (*save)(atom_t a, IOSTREAM *s); atom_t (*load)(IOSTREAM *s); ... } PL_blob_t;
For each type, exactly one such structure should be allocated. Its
first field must be initialised to PL_BLOB_MAGIC
. The
flags is a bitwise or of the following constants:
- PL_BLOB_TEXT
- If specified, the blob is assumed to contain text and is considered a normal Prolog atom. The (currently) two predefined blob types that represent atoms have this flag set. User-defined blobs may not specify this, even if they contain only text. Applications should not use the blob API to create normal text atoms or get access to the text represented by normal text atoms. Most applications should use PL_get_nchars() and PL_unify_chars() to get text from Prolog terms or create Prolog terms that represent text.
- PL_BLOB_UNIQUE
- If specified the system ensures that the blob-handle is a unique
reference for a blob with the given type, length and content. If this
flag is not specified, each lookup creates a new blob. Uniqueness is
determined by comparing the bytes in the blobs unless
PL_BLOB_NOCOPY
is also specified, in which case the pointers are compared. - PL_BLOB_NOCOPY
- By default the content of the blob is copied. Using this flag the blob
references the external data directly. The user must ensure the provided
pointer is valid as long as the atom lives. If
PL_BLOB_UNIQUE
is also specified, uniqueness is determined by comparing the pointer rather than the data pointed at. UsingPL_BLOB_UNIQUE
can be used to make a blob reference an arbitrary pointer where the pointer data may be reclaimed in the release() handler.
PL_BLOB_NOCOPY|
- PL_BLOB_WCHAR
- If
PL_BLOB_TEXT
is also set, then the text is made up ofpl_wchar_t
items and the blob's lenght is the number of bytes (that is, the number of characters timessizeof(pl_wchar_t)
). AsPL_BLOB_TEXT
, this flag should not be set in user-defined blobs.
The name field represents the type name as available to
Prolog. See also current_blob/2.
The other fields are function pointers that must be initialised to
proper functions or NULL
to get the default behaviour of
built-in atoms. Below are the defined member functions:
- void acquire(atom_t a)
- Called if a new blob of this type is created through PL_put_blob()
or
PL_unify_blob().
Note this this call is done as part of creating the blob. The call to PL_unify_blob()
may fail if the unification fails or cannot be completed due to a
resource error. PL_put_blob()
has no such error conditions. This callback is typically used to store
the
atom_t
handle into the content of the blob. Given a pointer to the content, we can now use PL_unify_atom() to bind a Prolog term with a reference to the pointed to object. If the content of the blob can be modified (PL_BLOB_UNIQUE
is not present) this is the only way to get access to theatom_t
handle that belongs to this blob. IfPL_BLOB_UNIQUE
is provided and respected, PL_unify_blob() given the same pointer and length will produce the sameatom_t
handle. - int release(atom_t a)
- The blob (atom) a is about to be released. This function can
retrieve the data of the blob using PL_blob_data().
If it returns
FALSE
, the atom garbage collector will not reclaim the atom. The release(f)unction is called when the atom is reclaimed by the atom garbage collector. For critical resources such as file handl