# PL\_call\_predicate on external/foreign predicate,

**URL:** <https://swi-prolog.discourse.group/t/pl-call-predicate-on-external-foreign-predicate/7092>\
**Category:** General\
**Created:** [December 21, 2023, 10:48am UTC](https://swi-prolog.discourse.group/t/pl-call-predicate-on-external-foreign-predicate/7092 "2023-12-21T10:48:36Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![hansvas](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/hansvas/32/5985_2.png) [@hansvas](https://swi-prolog.discourse.group/u/hansvas)\
**Post date:** [December 21, 2023, 10:48am UTC](https://swi-prolog.discourse.group/t/pl-call-predicate-on-external-foreign-predicate/7092/1 "2023-12-21T10:48:36Z")

</div>

Hi, i ve got a simple foreign predicate (just for testing), in this sample i named it add\_four. It is registered with SWI Prolog within the RegisterForeign in the following code example.

I also wrote a wrapper class for most of the functionality swi-prolog provides. It will be called correctly and runs successful. But the call to pl\_put\_integer or pl\_unify\_integer did not manipulate the value of trm+1.

For internal predicates the Mechanism TProlog.CallPredicate works fine, but for the foreign predicate, i am not able to get a corret result in the provided anonymus method for trm + 1; Its always of the same value  
as it was before (99) the result should be 8. The foreign predicate will be called correctly.

function add\_four (t : term\_t; arity : integer; var context : pointer) : foreign\_t;  
var i : Integer;  
begin  
result := c\_true;  
PL\_get\_Integer(t,i);  
// pl\_put\_integer(t+1,i+4);  
PL\_unify\_integer(t+1,i+4);  
end;

var registered : Boolean = False;

procedure RegisterForeign;  
begin  
if not registered then  
try  
installed\_add\_four := PL\_Register\_foreign  
( ‘add\_four’, 2, @add\_four, PL\_FA\_VARARGS);  
installed\_listSender := PL\_Register\_foreign  
(‘l\_sender’, 2, @listSender, PL\_FA\_VARARGS);  
installed\_listRetriever := PL\_Register\_foreign  
(‘l\_retriever’, 2, @listRetriever, PL\_FA\_VARARGS);  
finally  
registered := True;  
end;  
end;

Function TProlog.CallPredicate(Const aName : AnsiString;  
Params : Array Of Const;  
cleanFunc : TPredicatedFunc = Nil ) : Boolean;  
Var p : rPredicate;  
trm : term\_t;  
Begin  
result := True;  
If FPredicates.TryGetValue(aName, p) Then  
Begin  
trm := makeTerm (p, params);  
result := CHCK(PL\_call\_predicate(Nil, PL\_Q\_NORMAL, p.predicate, trm));  
If Assigned(cleanFunc) Then  
result := result and cleanFunc(self,p,trm);  
End;  
End;

And this is how it gets called:

v := 4;  
x := 99;  
p.CallPredicate(prd, [v,x],

```
// will be called after callpredicate is succesful
function (p : TProlog; pred : rPredicate; var trm : term_t) : Boolean
var l : String;
begin
 result := True;
 ttype := pl_term_type(trm+1);
 case ttype of
    PL_INTEGER : if chck(PL_get_integer(trm+1, solution)) then
      begin
        l := IntToStr(solution);
        M.Lines.Add('Ergebnis: ' + l);
      end; // A integer
    PL_RATIONAL ... : ; // A rational number
  end;

end );

```
