在外部程序中运行 Mathematica

在外部程序中运行 Mathematica 需要利用 MathLink 的许多特点. 第一个问题是如何将 MathLink 连接到Mathematica.

MathLink 模板产生能从 Mathematica 调用的外部程序时,建立 MathLink 连接的源代码会自动产生,在外部程序中要做的就是调用 MLMain(argc, argv). 但一般要调用几个函数去建立 MathLink 连接.

MLENVMLInitialize(0)初始化 MathLink 库函数
MLINKMLOpenArgcArgv(MLENV env,int argc,char**argv,int*errno)
打开一个 MathLink 连接,从 数组取参数
MLINKMLOpenString(MLENV env,char*string,int*errno)
打开一个 MathLink 连接,从一个字符串取参数
intMLActivate(MLINK link)激活一个 MathLink 连接,等待另一端的程序响应
voidMLClose(MLINK link)关闭 MathLink 连接
voidMLDeinitialize(MLENV env)取消对 MathLink 库函数的初始化

打开和关闭 MathLink 连接.

包括标准 MathLink 头函数.
#include "mathlink.h"
int main(int argc, char *argv[]) {
   MLENV env;
MLINK link;
int errno;
初始化 MathLink 库函数.
   env = MLInitialize(0);
打开一个 MathLink 连接,使用传递到主程序的同一变量.
   link = MLOpenArgcArgv(env, argc, argv, &errno);
激活连接,等待其他程序响应.
   MLActivate(link);
   ...
}

传递给 MLOpenArgcArgv() 常常是直接从整个程序开始时传递给 得到.

数组中的元素是字符串,它反映 Mathematica 函数 LinkLaunchLinkCreateLinkConnect 的变量选项.

"-linklaunch"LinkLaunch["name"] 一样的运算
"-linkcreate"LinkCreate["name"] 一样的运算
"-linkconnect"LinkConnect["name"] 一样的运算
"-linkname","name"给出要使用的名称
"-linkprotocol","protocol"给出要用的连接协议( 等)

可能传递给 MLOpenArgcArgv() 数组元素.

MLOpenArgcArgv() 的另一种选择是 MLOpenString(),它将参数并置在一个字符串中,参数中间有空格.

打开 MathLinkMathematica 内核的连接后,就能用标准的 MathLink 函数交换数据.

intMLEndPacket(MLINK link)指明包的结尾
intMLNextPacket(MLINK link)寻找下一个包的头部
intMLNewPacket(MLINK link)跳到当前包的结尾

Mathematica 内核通讯的常用函数.

MLPutFunction() 等发生了所有包以后,MathLink 要求调用 MLEndPacket() 去确认同步性和一致性.

在编写与 Mathematica 内核直接通讯的外部程序时,一个主要的方面是处理内核可以产生的各种包.

函数 MLNextPacket() 寻找下一个来自于内核的包的头部,返回一个表面该包类型的常数.

Mathematica
常数
ReturnPacket[expr]RETURNPKT计算结果
ReturnTextPacket["string"]RETURNTEXTPKT结果的文本形式
InputNamePacket["name"]INPUTNAMEPKT输入行名称
OutputNamePacket["name"]OUTPUTNAMEPKT输出行名称
TextPacket["string"]TEXTPKTPrint 等函数的文本输出
MessagePacket[symb,"tag"]MESSAGEPKTMathematica 产生的消息名称
InputPacket["prompt"]INPUTPKT响应 Input 函数的请求
CallPacket[i,list]CALLPKT调用外部函数的请求

MLNextPacket() 识别的一些包.

一直从一个链接读数据,遇到一个错误或发现一个 ReturnPacket 时停止.
while ((p = MLNextPacket(link)) && p != RETURNPKT)
MLNewPacket(link);

将一个完整的前端写入 Mathematica 时,需要处理产生的各种类型的包. 一般是在 MLNextPacket()返回值上设置一个适当的转换来完成这一任务.

MathLink Developer Kit 含有几个简单但完整的前端源代码的样本.

intMLReady(MLINK link)测试链接中是否有待读的数据
int MLReadyParallel (MLENV e, MLINK *links, int n, mltimeval t)
并行测试链接列表中是否有待读的数据
intMLFlush(MLINK link)刷新含有链接中待送数据的缓冲区

链接中的数据流.

诸如前端等更复杂的外部程序的特定之一是在等待从 Mathematica 发送的数据时进行运算. 而在调用 MLNextPacket() 等标准 MathLink 库函数时,直到该函数所需的数据备齐前,程序是锁住的.

反复调用 MLReady()可避免锁住,当 MLReady() 返回的不是 值时,仅调用 MLNextPacket() 等函数即可. MLReady()Mathematica 函数 LinkReadyQ 相似.

注意,MathLink 有时会将要发送的数据放在缓冲区内. 为了保证所有数据被送出. 应该调用 MLFlush(). 这之后调用 MLReady() 和等待返回的数据才有意义.

New to Mathematica? Find your learning path »
Have a question? Ask support »