9 The PREDICATE macro
The PREDICATE macro is there to make your code look nice, taking care of the interface to the C-defined SWI-Prolog kernel as well as mapping exceptions. Using the macro
PREDICATE(hello, 1)
is the same as writing:
static foreign_t pl_hello__1(PlTermv _av);
static foreign_t
_pl_hello__1(term_t t0, int arity, control_t ctx)
{ try
{ return pl_hello__1(PlTermv(1, t0));
} catch ( PlTerm &ex )
{ return ex.raise();
}
}
static PlRegister _x_hello__1("hello", 1, _pl_hello__1);
static foreign_t
pl_hello__1(PlTermv _av)
The first function converts the parameters passed from the Prolog kernel to a PlTermv instance and maps exceptions raised in the body to Prolog exceptions. The PlRegister global constructor registers the predicate. Finally, the function header for the implementation is created.
9.1 Controlling the Prolog destination module
With no special precautions, the predicates are defined into the
module from which load_foreign_library/1
was called, or in the module
user if there is no Prolog context from which to deduce the
module such as while linking the extension statically with the Prolog
kernel.
Alternatively, before loading the SWI-Prolog include file, the macro PROLOG_MODULE may be defined to a string containing the name of the destination module. A module name may only contain alpha-numerical characters (letters, digits, _). See the example below:
#define PROLOG_MODULE "math"
#include <SWI-Prolog.h>
#include <math.h>
PREDICATE(pi, 1)
{ A1 = M_PI;
}
?- math:pi(X). X = 3.14159