The first example shows how you can package a call to a Prolog goal that is
known to be determinate. Here, the C function fred hides the call to
Prolog. However, the servant must be initiated by a call to
QP_ipc_create_servant() before it can be called.
Prolog Specification
external(fred, xdr, fred(+integer,-integer,+integer)).
fred(X, Y, Z) :- ...
C routine
int fred(i, j)
int i, j;
{
static int fredp = -1;
int k;
if (fredp < 0) { /* initialize */
fredp = QP_ipc_lookup("fred");
if (fredp < 0)
DieBecause("couldn't find fred");
}
/* send the request */
QP_ipc_prepare(fredp, i, j);
/* get the answer back */
if (QP_ipc_next(fredp, &k))
DieBecause("fred failed");
/* known determinate, so close request */
QP_ipc_close();
/* return the answer */
return k;
}
The second example shows an entire program and how all types of arguments
are be passed. It also shows how QP_ipc_atom_from_string() and
QP_ipc_string_from_atom() can be used. In terms of functionality, this is
not a very interesting program, and the conversion between atoms and
strings is just to give an example.
Prolog Specification
external(dupl, xdr, duplicate(-integer,+integer,-string,+string,
-float,+float,-atom,+atom)).
duplicate(A, A, B, B, C, C, D, D).
C program:
main()
{
int pdupl;
char host[20], savestate[50];
int iint, oint;
char istr1[20], istr2[20], ostr1[20], ostr2[20];
float iflt, oflt;
QP_atom iatom, oatom;
printf("Enter host and savestate: ");
scanf("%s%s", host, savestate);
if (QP_ipc_create_servant(host,savestate,"servant_out"))
DieBecause("Error starting up servant");
pdupl = QP_ipc_lookup("dupl");
if (pdupl < 0) DieBecause("dupl not defined");
for (;;) { /* loop until break */
printf("Enter int, str, flt, str: ");
if (scanf("%d%s%f%s",&iint,istr1,&iflt,istr2) != 4)
break;
/* get atom for the string typed in */
iatom = QP_ipc_atom_from_string(istr2);
/* send the request */
if (QP_ipc_prepare(pdupl, iint, istr1, iflt, iatom))
DieBecause("dupl prepare error");
/* get answer back, and convert atom back to string */
QP_ipc_next(pdupl, &oint, ostr1, &oflt, &oatom);
QP_ipc_string_from_atom(oatom, ostr2);
/* close request because we want only one answer */
if (QP_ipc_close()) printf("ERROR closing\n");
printf("Answer is: %d %s %G %s(%d)\n",
oint, ostr1, oflt, ostr2, oatom);
}
if (QP_ipc_shutdown_servant())
DieBecause("Error shutting down servant");
}
The third example shows how to retrieve multiple answers:
Prolog Specification
external(table, xdr, table(-string,-integer)).
table(samuel, 34).
table(sarah, 54).
...
C program
main()
{
char host[20], savestate[50];
int ptable, ret;
char strval[40];
int intval;
printf("Enter host and savestate: ");
scanf("%s%s", host, savestate);
if (QP_ipc_create_servant(host,savestate,"servant_out"))
DieBecause("Error starting up servant");
ptable = QP_ipc_lookup("table");
if (ptable < 0) {
printf("table not defined\n");
return;
}
/* send the request */
QP_ipc_prepare(ptable);
/* retrieve and print ALL answers */
while (!(ret = QP_ipc_next(ptable, strval, &intval)))
printf("String: %s, Integer: %d\n", strval,intval);
/* note no close, since we retrieved all the answers! */
if (ret == -1) printf("All answers retrieved\n");
else printf("Error retrieving answers\n");
if (QP_ipc_shutdown_servant())
DieBecause("Error shutting down servant");
}
The final example shows how one could write a C function to turn Prolog's message tracing (see ipc-rpc-tra) on and off.
Prolog Specification
external(settrace, xdr, settrace(+string)).
settrace(X) :- msg_trace(_,X).
C routine
void settrace(OnOff)
char *OnOff;
{
static int psettrace = -1;
int k;
if (psettrace < 0) {
psettrace = QP_ipc_lookup("settrace");
if (psettrace < 0)
DieBecause("couldn't find settrace");
}
QP_ipc_prepare(psettrace, OnOff);
if (QP_ipc_next(psettrace))
DieBecause("settrace failed");
QP_ipc_close();
}