外部プログラム内から Mathematica を呼び出す

外部プログラム内から Mathematica を呼び出すためには MathLink の一般的な多くの機能を利用する必要がある.まず最初は,Mathematica との MathLink 接続を確立することである.

Mathematica から呼出し可能な外部プログラムを作成するのに MathLink テンプレートを利用した場合は,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)
文字列1つからパラメータを取って,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()の代りに,引数をスペース文字で区切って連結した1つの文字列として受け取るMLOpenString()を利用することもできる.

Mathematica カーネルとの MathLink 接続を開いたあとは,標準の MathLink 関数を呼んでデータを,MathLink 接続上で交換できるようになる.

intMLEndPacket(MLINK link)パケットの最後を示す
intMLNextPacket(MLINK link)次のパケットの頭部を見付ける
intMLNewPacket(MLINK link)現行のパケットの最後までスキップする

Mathematica カーネルと通信するためによく使う関数

MLPutFunction()その他でパケットを全部送り終えたら,MLEndPacket()を呼んで,MathLink と同期,調和を取る必要がある.

Mathematica カーネルと直に通信する外部プログラムを書く第1の目的は,カーネルが生成するさまざまな種類のパケットを処理することである.

関数MLNextPacket()はカーネルからくる次のパケットの頭部を見付け,パケットの種類を表す定数を返す.

Mathematica パケット
定数
ReturnPacket[expr]RETURNPKT計算の結果
ReturnTextPacket["string"]RETURNTEXTPKT結果のテキスト形式
InputNamePacket["name"]INPUTNAMEPKT入力行の名前
OutputNamePacket["name"]OUTPUTNAMEPKT出力行の名前
TextPacket["string"]TEXTPKTPrintのような関数が出したテキスト出力
MessagePacket[symb,"tag"]MESSAGEPKTMathematica が生成したメッセージ
InputPacket["prompt"]INPUTPKTInput関数への応答を要求する
CallPacket[i,list]CALLPKT外部関数の呼出しを要求する

MLNextPacket()が認識するパケットの一部

エラーが発生するか,ReturnPacketが見付かるまで,リンクからデータを読み続ける.
while ((p = MLNextPacket(link)) && p != RETURNPKT)
MLNewPacket(link);

Mathematica の完全なフロントエンドを書く場合は,カーネルが生成するあらゆる種類のパケットを処理する必要がある.MLNextPacket()が返す値に応じて適当にを書けば問題ない.

MathLink デベロッパーキットには,簡単だが完全なフロントエンドのソースコードがいくつか入っている.

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 »