外部程序中的表达式操作

Wolfram 语言表达式提供了处理各种数据的一般方法,有时需要在外部程序中使用这些表达式. C 语言等并没有提供保存一般 Wolfram 语言表达式的直接方式. 但这可以用 Wolfram Symbolic Transfer Protocol (WSTP) 库中提供的环回链接(loopback links)来完成. 环回链接是外部程序中的局部 WSTP 连接,可以向它写入后面读出的表达式.
WSLINKWSLoopbackOpen(stdenv,int*errno)
打开一个环回链接
voidWSClose(WSLINK link)
关闭一个回路链接
intWSTransferExpression(WSLINK dest,WSLINK src)
src 得到一个表达式并将它放入 dest
操作环回链接的函数.
打开一个环回链接:
...
wstp = WSLoopbackOpen(stdenv, &errno);
将表达式 Power[x,3] 放入环回链接中:
WSPutFunction(wstp, "Power", 2);
WSPutSymbol(wstp, "x");
WSPutInteger32(wstp, 3);
...
从这个环回链接中读出该表达式:
WSGetFunction(wstp, &head, &n);
WSGetSymbol(wstp, &sname);
WSGetInteger32(wstp, &k);
...
重新关闭这个环回链接:
WSClose(wstp);
可以用 WSTransferExpression() 去取一个通过 stdlink 从 Wolfram 语言中得到的一个表达式,然后把它保存在局部环回链接中以便后面处理.
也可以用 WSTransferExpression() 去取在局部环回链接中建立的表达式,然后再通过 stdlink 将它送回到 Wolfram 语言中.
21! 放到一个局部环回链接中:
...
WSPutFunction(wstp, "Factorial", 1);
WSPutInteger32(wstp, 21);
这里将头 FactorInteger 送到 Wolfram 语言:
WSPutFunction(stdlink, "FactorInteger", 1);
这里将 21! 从环回链接传送到 stdlink
WSTransferExpression(stdlink, wstp);
可以将任意表达式序列放入环回链接中. 一般可以按放入的顺序取出这些表达式.
从链接取出一个表达式后它就不再保存. 但可以用 WSCreateMark() 去标记一个链接中表达式序列的某一位置,强制 WSTP 去保存该标记之后的表达式以便后面访问.
WSMARKWSCreateMark(WSLINK link)
在链接中表达式序列的当前位置加一个标记
WSSeekMark(WSLINK link,WSMARK mark,int n)
返回到链接中指定标记后 n 个表达式的位置
WSDestroyMark(WSLINK link,WSMARK mark)
删除链接中的标记
在 WSTP 设置标记.
将整数 45 放入环回链接中:
...
WSPutInteger32(wstp, 45);
再将 33 放入该链接中:
WSPutInteger32(wstp, 33);
再将 76 放入:
WSPutInteger32(wstp, 76);
这里从该链接读出 4545 就不再保存:
WSGetInteger32(wstp, &i);
这里在链接的当前位置插入一个标记:
mark = WSCreateMark(wstp);
现在读 33
WSGetInteger32(wstp, &i);
接着读 76
WSGetInteger32(wstp, &i);
这里返回到标记位置:
WSSeekMark(wstp, mark, 0);
现在可以重新读 33
WSGetInteger32(wstp, &i);
重要的一点是完成之后要删除这些标记,避免保存那些不必要的表达式:
WSDestroyMark(wstp, mark);
WSTP 库提供的方法在打开和关闭环回链接中以及产生和删除它们之间的标记时是十分有效的. 要记住在一个链接中设立了标记后,WSTP 就保存该链接中在标记后的表达式,且保存一直持续到标记删除为止.
intWSGetNext(WSLINK link)
在链接上找出下一个对象的类型
intWSGetArgCount(WSLINK link,int*n)
将链接中函数变量的个数存为 n
intWSGetSymbol(WSLINK link,char**name)
得到符号名
intWSGetInteger32(WSLINK link,int*i)
得到机器整数
intWSGetReal64(WSLINK link,double*x)
得到机器浮点数
intWSGetString(WSLINK link,char**string)
得到字符串
从一个链接得到一些表达式的函数.
WSTKFUNC
组合函数头部和变量
WSTKSYM
Wolfram 语言符号
WSTKINT
整数
WSTKREAL
浮点数
WSTKSTR
字符串
WSGetNext() 返回的常数.
switch(WSGetNext(wstp)) {
这里读一个组合函数:
    case WSTKFUNC:
WSGetArgCount(wstp, &n);
recurse for head
for (i = 0; i < n; i++) {
recurse for each argument
}
这里读一个符号:
    case WSTKSYM:
WSGetSymbol(wstp, &name);
读一个机器整数:
    case WSTKINT:
WSGetInteger32(wstp, &i);

}
WSGetNext() 可以直接写出能读任何表达式的程序. WSTP 的工作方式是,函数的头部和变量作为相继的表达式在链接中出现,就可以逐个读入它.
注意,如果已经知道一个函数的头部是一个符号时,就可以用 WSGetFunction(),而不用 WSGetNext(). 这时,需要调用 WSReleaseSymbol() 去释放符号名占用的内存.
intWSPutNext(WSLINK link,int type)
准备向链接放一个具有指定类型的对象
intWSPutArgCount(WSLINK link,int n)
给出一个组合函数的变量个数
intWSPutSymbol(WSLINK link,char*name)
向链接放一个符号
intWSPutInteger32(WSLINK link,int i)
放一个机器整数
intWSPutReal64(WSLINK link,double x)
放一个机器浮点数
intWSPutString(WSLINK link,char*string)
放一个字符串
向链接放表达式的函数.
WSPutNext() 给出使用从 wstp.h 头文件得到的 MLTKFUNC 常数的表达式类型,这与 WSGetNext() 相同.