外部プログラム内から Mathematica を呼び出す
外部プログラム内から Mathematica を呼び出すためには MathLink の一般的な多くの機能を利用する必要がある.まず最初は,Mathematica との MathLink 接続を確立することである.
Mathematica から呼出し可能な外部プログラムを作成するのに MathLink テンプレートを利用した場合は,MathLink 接続を確立するためのソースコードが自動的に作成され,外部プログラムは単にMLMain(argc, argv)を呼び出すだけでよい.しかし,一般に,MathLink 接続を確立するには関数を何個か呼び出す必要がある.
| MLENVMLInitialize(0) | MathLink ライブラリ関数を初期化する |
| MLINKMLOpenArgcArgv(MLENV env,int argc,char**argv,int*errno) | |
| MLINKMLOpenString(MLENV env,char*string,int*errno) | |
| 文字列1つからパラメータを取って,MathLink 接続を開く | |
| intMLActivate(MLINK link) | MathLink 接続を活性化し,他端のプログラムが応答するのを待つ |
| voidMLClose(MLINK link) | MathLink 接続を閉じる |
| voidMLDeinitialize(MLENV env) | MathLink ライブラリ関数を終了する |
#include "mathlink.h"
int main(int argc, char *argv[]) {
MLENV env;
MLINK link;
int errno;
env = MLInitialize(0);
link = MLOpenArgcArgv(env, argc, argv, &errno);
MLActivate(link);
...
}
MLOpenArgcArgv()に渡す
は,プログラムを開始させたときに
に渡される
が直接使われることがほとんどである.
中の要素は,Mathematica 関数のLinkLaunch,LinkCreateとLinkConnectで使用する引数やオプションを表す文字列である.
| "-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"] | TEXTPKT | Printのような関数が出したテキスト出力 |
| MessagePacket[symb,"tag"] | MESSAGEPKT | Mathematica が生成したメッセージ |
| InputPacket["prompt"] | INPUTPKT | Input関数への応答を要求する |
| CallPacket[i,list] | CALLPKT | 外部関数の呼出しを要求する |
MLNextPacket()が認識するパケットの一部
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()を呼び,返ってくるデータを待つのみである.
