Next: , Previous: , Up: cpg-bif   [Contents][Index]


12.3.11 SP_define_c_predicate()

Synopsis

#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.

Arguments

name

The predicate name.

arity

The predicate arity.

module

The predicate module name.

proc

The function.

stash

See below.

Return Value

Nonzero on success, and 0 otherwise.

Description

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.

Examples

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.9.0 …
Licensed to SICS
| ?- square(4711, X).
X = 22193521 ?
yes
| ?- square(not_an_int, X).
no

See Also

See Calling C from Prolog.



Send feedback on this subject.