|
2.13.14 外部プログラム内から Mathematicaを呼び出す
外部プログラム内から Mathematicaを呼び出すためには MathLinkの一般的な多くの機能を利用する必要がある. まず最初は, MathematicaとのMathLinkコネクションを確立することである.
Mathematicaから呼出し可能な外部プログラムを作成するのに MathLinkテンプレートを利用した場合は, MathLinkコネクションを確立するためのソースコードが自動的に作成され,外部プログラムは単に MLMain(argc, argv)を呼び出すだけでよい. しかし,一般に, MathLinkコネクションを確立するには関数を何個か呼び出す必要がある.

MathLinkコネクションの開閉
MathLinkの標準ヘッダファイルを含む.
#include "mathlink.h"
int main(int argc, char *argv[]) {
MLENV env;
MLINK link;
long errno;
MathLinkライブラリ関数を初期化する.
env = MLInitialize(0);
MathLinkコネクションを開く.メインプログラムに与えられた引数を使う.
link = MLOpenArgv(env, argv, argv+argc, &errno);
コネクションを活性化し,もう一方のプログラムが応答するのを待つ.
MLActivate(link);
...
}
MLOpenArgv()に渡すargvは,プログラムを開始させたときに main()に渡される argvが直接使われることがほとんどである. MLOpenArgv()はargv配列の最初と最後を示すポインタを引数に取ることに注意すること. argcを直接使わなければ, intのサイズを知る必要がなくなる.
argv中の要素は, Mathematica関数の LinkLaunch , LinkCreateと LinkConnectで使用する引数やオプションを表す文字列である.

MLOpenArgv()に渡す配列 argvに設定可能な要素
MLOpenArgv()の代りに,引数をスペース文字で区切って連結した1つの文字列として受け取る MLOpenString()を利用することもできる.
Mathematicaカーネルとの MathLinkコネクションを開いたあとは,標準の MathLink関数を呼んでデータを, MathLinkコネクション上で交換できるようになる.

Mathematicaカーネルと通信するためによく使う関数
MLPutFunction()その他でパケットを全部送り終えたら, MLEndPacket()を呼んで,MathLinkと同期,調和を取る必要がある.
Mathematicaカーネルと直に通信する外部プログラムを書く第1の目的は,カーネルが生成するさまざまな種類のパケットを処理することである.
関数 MLNextPacket()はカーネルからくる次のパケットの頭部を見付け,パケットの種類を表す定数を返す.

MLNextPacket()が認識するパケットの一部
エラーが発生するか, ReturnPacketが見付かるまで,リンクからデータを読み続ける.
while ((p = MLNextPacket(link)) && p != RETURNPKT)
MLNewPacket(link);
Mathematicaの完全なフロントエンドを書く場合は,カーネルが生成するあらゆる種類のパケットを処理する必要がある. MLNextPacket()が返す値に応じて適当に switchを書けば問題ない.
MathLinkデベロッパーキットには,簡単だが完全なフロントエンドのソースコードがいくつか入っている.

リンク上データの流れ
フロントエンドのような,より洗練された外部プログラムでは, Mathematicaが送ってくるデータを待つ間でも,なんらかのオペレーションを実行する必要がある場合もある.MLNextPacket()のような標準 MathLinkライブラリ関数を呼び出すと,プログラムはその関数が必要とするすべてのデータが得られるまで実行をブロックしてしまう.
MLReady()を繰り返し呼び, MLReady()が 0を返さなくなった時点で MLNextPacket()を呼ぶようにすれば,ブロックするのを避けることができる.MLReady()は Mathematica関数LinkReadyQと類似の関数である.
MathLinkが,送信が指令されたデータをバッファリングする場合もある.必要なデータを確実に送信するためには MLFlush()を使う. MLFlush()した後は MLReady()を呼び,返ってくるデータを待つのみである.
|