Next: cpg-ref-SP_deinitialize, Previous: cpg-ref-SP_cut_query, Up: cpg-bif [Contents][Index]
SP_define_c_predicate()#include <sicstus/sicstus.h>
typedef int
SP_CPredFun(SP_term_ref goal,
void *stash);
int
SP_define_c_predicate(char *name,
int arity,
char *module,
SP_CPredFun *proc,
void *stash);
Defines a Prolog predicate such that when the Prolog predicate is called it will call a C function with a term corresponding to the Prolog goal.
The predicate name.
The predicate arity.
The predicate module name.
The function.
See below.
Nonzero on success, and 0 otherwise.
The Prolog predicate module:name/arity will be
defined (the module module must already exist). The
stash argument can be anything and is simply passed as the
second argument to the C function proc.
The C function should return SP_SUCCESS for success and
SP_FAILURE for failure. The C function may also call
SP_fail() or SP_raise_exception() in which case the return
value will be ignored.
Here is an end-to-end example of the above:
% square.pl
foreign_resource(square, [init(square_init)]).
:- load_foreign_resource(square).
// square.c
#include <sicstus/sicstus.h>
static int square_it(SP_term_ref goal, void *stash)
{
SP_integer arg1;
SP_term_ref tmp = SP_new_term_ref();
SP_term_ref square_term = SP_new_term_ref();
// goal will be a term like square(42,X)
SP_get_arg(1,goal,tmp); // extract first arg
if (!SP_get_integer(tmp,&arg1))
return SP_FAILURE; // type check first arg
SP_put_integer(square_term, arg1*arg1);
SP_get_arg(2,goal,tmp); // extract second arg
// Unify output argument.
// SP_put_integer(tmp,…) would *not* work!
return (SP_unify(tmp, square_term) ? SP_SUCCESS : SP_FAILURE);
}
void square_init(int when)
{
(void)when; // unused
// Install square_it as user:square/2
SP_define_c_predicate("square", 2, "user", square_it, NULL);
}
# terminal
% splfr square.pl square.c % sicstus -f -l square % compiling /home/matsc/tmp/square.pl... % loading foreign resource /home/matsc/tmp/square.so in module user % compiled /home/matsc/tmp/square.pl in module user, 0 msec 816 bytes SICStus 4.10.1 … Licensed to SICS | ?- square(4711, X). X = 22193521 ? yes | ?- square(not_an_int, X). no