Manipulating Expressions in External Programs
Wolfram Language expressions provide a very general way to handle all kinds of data, and you may sometimes want to use such expressions inside your external programs. A language like C, however, offers no direct way to store general Wolfram Language expressions. It is nevertheless possible to do this by using the loopback links provided by the Wolfram Symbolic Transfer Protocol (WSTP) library. A loopback link is a local WSTP connection inside your external program, to which you can write expressions that can later be read back.
|open a loopback link|
|voidWSClose(WSLINK link)||close a link|
|intWSTransferExpression(WSLINK dest,WSLINK src)||get an expression from src and put it onto dest|
wstp = WSLoopbackOpen(stdenv, &errno);
WSPutFunction(wstp, "Power", 2);
WSGetFunction(wstp, &head, &n);
WSPutFunction(wstp, "Factorial", 1);
WSPutFunction(stdlink, "FactorInteger", 1);
And once you have got an expression off the link it is usually no longer saved. But by using WSCreateMark() you can mark a particular position in a sequence of expressions on a link, forcing WSTP to save every expression after the mark so that you can go back to it later.
|WSMARKWSCreateMark(WSLINK link)||create a mark at the current position in a sequence of expressions on a link|
|WSSeekMark(WSLINK link,WSMARK mark,int n)|
|go back to a position n expressions after the specified mark on a link|
|WSDestroyMark(WSLINK link,WSMARK mark)||destroy a mark in a link|
mark = WSCreateMark(wstp);
WSSeekMark(wstp, mark, 0);
The way the WSTP library is implemented, it is very efficient to open and close loopback links, and to create and destroy marks in them. The only point to remember is that as soon as you create a mark on a particular link, WSTP will save subsequent expressions that are put on that link, and will go on doing this until the mark is destroyed.
|intWSGetNext(WSLINK link)||find the type of the next object on a link|
|intWSGetArgCount(WSLINK link,int*n)||store in n the number of arguments for a function on a link|
|intWSGetSymbol(WSLINK link,char**name)||get the name of a symbol|
|intWSGetInteger32(WSLINK link,int*i)||get a machine integer|
|intWSGetReal64(WSLINK link,double*x)||get a machine floating‐point number|
|intWSGetString(WSLINK link,char**string)||get a character string|
|WSTKFUNC||composite function—head and arguments|
|WSTKSYM||Wolfram Language symbol|
Constants returned by WSGetNext().
recurse for head
for (i = 0; i < n; i++) Null
recurse for each argument
By using WSGetNext() it is straightforward to write programs that can read any expression. The way WSTP works, the head and arguments of a function appear as successive expressions on the link, which you read one after another.
Note that if you know that the head of a function will be a symbol, then you can use WSGetFunction() instead of WSGetNext(). In this case, however, you still need to call WSReleaseSymbol() to disown the memory used to store the symbol name.
|intWSPutNext(WSLINK link,int type)||prepare to put an object of the specified type on a link|
|intWSPutArgCount(WSLINK link,int n)||give the number of arguments for a composite function|
|put a symbol on the link|
|intWSPutInteger32(WSLINK link,int i)||put a machine integer|
|intWSPutReal64(WSLINK link,double x)||put a machine floating‐point number|
|put a character string|