Before going into a detailed description of the C++ classes we present a few examples illustrating the “feel” of the interface.
This simple example shows the basic definition of the predicate hello/1 and how a Prolog argument is converted to C-data:
PREDICATE(hello, 1)
{ cout << "Hello " << A1.as_string() << endl;
  return true;
}
The arguments to PREDICATE() 
are the name and arity of the predicate. The macros A<n> 
provide access to the predicate arguments by position and are of the 
type PlTerm. The C or C++ string for a PlTerm 
can be extracted using as_string(), 
or as_wstring() methods;25The 
C-string values can be extracted from std::string by using c_str(), 
but you must be careful to not return a pointer to a local/stack value, 
so this isn't recommende. and similar access methods 
provide an easy type-conversion for most Prolog data-types, using the 
output of write/1 
otherwise:
?- hello(world). Hello world Yes ?- hello(X) Hello _G170 X = _G170
This example shows arithmetic using the C++ interface, including unification, type-checking, and conversion. The predicate add/3 adds the two first arguments and unifies the last with the result.
PREDICATE(add, 3)
{ return A3.unify_integer(A1.as_long() + A2.as_long());
}
You can use your own variable names instead of A1,
A2, etc.:
PREDICATE(add, 3)  // add(+X, +Y, +Result)
{ PlTerm x(A1);
  PlTerm y(A2);
  PlTerm result(A3);
  return result.unify_integer(x.as_long() + y.as_long());
}
or more compactly:
PREDICATE(add, 3)  // add(+X, +Y, +Result)
{ auto x = A1, y = A2, result = A3;
  return result.unify_integer(x.as_long() + y.as_long());
}
The as_long() method for a PlTerm performs a PL_get_long_ex() 
and throws a C++ exception if the Prolog argument is not a Prolog 
integer or float that can be converted without loss to a
long. The unify_integer() method of PlTerm 
is defined to perform unification and returns true or false 
depending on the result.
?- add(1, 2, X). X = 3. ?- add(a, 2, X). [ERROR: Type error: `integer' expected, found `a'] Exception: ( 7) add(a, 2, _G197) ?
This example is a bit harder. The predicate average/3 is defined to take the template average(+Var, :Goal, -Average) , where Goal binds Var and will unify Average with average of the (integer) results.
PlQuery takes the name of a predicate and the 
goal-argument vector as arguments. From this information it deduces the 
arity and locates the predicate. The method PlQuery::next_solution() 
yields
true if there was a solution and false 
otherwise. If the goal yields a Prolog exception, it is mapped into a 
C++ exception. A return to Prolog does an implicit “cut” (PL_cut_query()); 
this can also be done explicitly by the PlQuery::cut() 
method.
PREDICATE(average, 3) /* average(+Templ, :Goal, -Average) */
{ long sum = 0;
  long n = 0;
  PlQuery q("call", PlTermv(A2));
  while( q.next_solution() )
  { sum += A1.as_long();
    n++;
  }
  return A3.unify_float(double(sum) / double(n));
}
?- [user]. |: p(1). |: p(10). |: p(20). |: % user://1 compiled 0.00 sec, 3 clauses true. ?- average(X, p(X), Average). Average = 10.333333333333334.