在外部程序中运行 Wolfram 系统
在外部程序中运行 Wolfram 系统需要利用 WSTP(Wolfram Symbolic Transfer Protocol) 的许多特点. 第一个问题是如何将 WSTP 连接到 Wolfram 系统.
用 WSTP 模板产生能从 Wolfram 语言调用的外部程序时,建立 WSTP 连接的源代码会自动产生,在外部程序中要做的就是调用 WSMain(argc,argv). 但一般要调用几个函数去建立 WSTP 连接.
WSENV WSInitialize(0) | 初始化 WSTP 库函数 |
WSLINK WSOpenArgcArgv(WSENV env,int argc,char**argv,int*errno) | |
打开一个 WSTP 连接,从 argv 数组取参数 | |
WSLINK WSOpenString(WSENV env,char*string,int*errno) | |
打开一个 WSTP 连接,从一个字符串取参数 | |
int WSActivate(WSLINK link) | 激活一个 WSTP 连接,等待另一端的程序响应 |
void WSClose(WSLINK link) | 关闭 WSTP 连接 |
void WSDeinitialize(WSENV env) | 取消对 WSTP 库函数的初始化 |
#include "mathlink.h"
int main(int argc, char *argv[]) {
WSENV env;
WSLINK link;
int errno;
env = WSInitialize(0);
link = WSOpenArgcArgv(env, argc, argv, &errno);
WSActivate(link);
...
}
"-linklaunch" | 像 LinkLaunch["name"] 一样的运算 |
"-linkcreate" | 像 LinkCreate["name"] 一样的运算 |
"-linkconnect" | 像 LinkConnect["name"] 一样的运算 |
"-linkname","name" | 给出要使用的名称 |
"-linkprotocol","protocol" | 给出要用的连接协议(TCPIP,Pipes 等) |
int WSEndPacket(WSLINK link) | 指明包的结尾 |
int WSNextPacket(WSLINK link) | 寻找下一个包的头部 |
int WSNewPacket(WSLINK link) | 跳到当前包的结尾 |
函数 WSNextPacket() 寻找下一个来自于内核的包的头部,返回一个表面该包类型的常数.
Wolfram 语言包 | 常数 | |
ReturnPacket[expr] | RETURNPKT | 计算结果 |
ReturnTextPacket["string"] | RETURNTEXTPKT | 结果的文本形式 |
InputNamePacket["name"] | INPUTNAMEPKT | 输入行名称 |
OutputNamePacket["name"] | OUTPUTNAMEPKT | 输出行名称 |
TextPacket["string"] | TEXTPKT | Print 等函数的文本输出 |
MessagePacket[symb,"tag"] | MESSAGEPKT | Wolfram 语言产生的消息名称 |
InputPacket["prompt"] | INPUTPKT | 响应 Input 函数的请求 |
CallPacket[i,list] | CALLPKT | 调用外部函数的请求 |
WSNextPacket()识别的一些包.
一直从一个链接读数据,遇到一个错误或发现一个 ReturnPacket 时停止:
while ((p = MLNextPacket(link)) && p != RETURNPKT)
MLNewPacket(link);
int WSReady(WSLINK link) | 测试链接中是否有待读的数据 |
int WSReadyParallel (WSENV e, WSLINK *links, int n, mltimeval t) | |
并行测试链接列表中是否有待读的数据 | |
int WSFlush(WSLINK link) | 刷新含有链接中待送数据的缓冲区 |
诸如前端等更复杂的外部程序的特定之一是在等待从 Wolfram 语言发送的数据时进行运算. 而在调用 WSNextPacket() 等标准 WSTP 库函数时,直到该函数所需的数据备齐前,程序是锁住的.
反复调用 WSReady() 可避免锁住,当 WSReady()返回的不是 0 值时,仅调用 WSNextPacket() 等函数即可. WSReady() 与 Wolfram 语言函数 LinkReadyQ 相似.