This section describes passing Prolog terms to a foreign function and receiving Prolog terms from a foreign function. For the current release this interface is supported only for C.
There is a difference between passing atomic objects (atoms, floats,
db_reference and integers) and generic Prolog terms through the
foreign interface. Generic Prolog terms passed to a C function (using
+term
) are not converted to any representation in C. Instead the
foreign function in C gets a reference to the Prolog term, which is of
type QP_term_ref
(defined in <quintus/quintus.h>
).
Similarly when a generic term is returned (using -term
or [-term]
)
from a foreign function there is no conversion of any data structures
in the foreign language into an equivalent Prolog representation. The
foreign function has to return a reference to a Prolog term, which it
originally got from Prolog or from one of the functions/macros
provided to manipulate Prolog terms such as the QP_put*
and
QP_cons*
families of functions.
When Prolog terms are referred to from C, what the C function holds is an indirect reference to the Prolog term. There is a reason for this indirection. Prolog terms live in the Prolog global stack, and migrate when Prolog does garbage collection or stack shifting. If the C function held onto a direct reference to a Prolog term it would become invalid after one of these memory management operations. Prolog cannot update and relocate these references that C is holding onto since it is impossible to distinguish between Prolog references and other integers and pointers that C holds onto.
The C code should also be aware of the scope (or lifetime) of the references to Prolog terms passed to it. Once you return to Prolog from a call to a foreign function, all the references to Prolog terms passed to the foreign function are invalid. All references to terms created by the foreign function are also invalid.
WARNING: You should not store references to prolog terms into global variables in the foreign language.
The scope of references to terms are more restricted when C calls Prolog.
If Prolog returns a term as a result of a C call to a Prolog predicate,
that term is valid only till the call for the next solution from that
Prolog predicate (using QP_next_solution()
).
This also holds true for terms created in C. If you create a term after one
call to a Prolog predicate then the reference to that term is only valid
till the call for next solution from that Prolog predicate.
.