login

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