|
2.13.9 外部プログラムとの双方向通信
Installを使ってMathLink適合プログラムをインストールする場合,そのプログラムの振舞いはやや単純化されたMathematicaカーネルと似ている.外部プログラム中の関数を呼び出すときは必ず CallPacketがプログラムに送られ,プログラムは呼び出された関数の結果を ReturnPacketで包み込んで返送する.
外部プログラムをインストールする.プログラムとのコネクションに用いられる LinkObjectが返される.
In[6]:= link = Install["bitsprog"]
Out[6]= 
関数 ExternalCallは CallPacketを外部プログラムに送信する. CallPacketの第1引数は外部プログラム中のどの関数を呼ぶべきかを示している.
In[7]:= ?bits


LinkWriteを使い呼出し用パケッ ト(CallPacket)を送ることも可能である.第1引数は外部プログラムにあるどの関数を呼び出すかを指定する.
In[8]:= LinkWrite[link, CallPacket[0, {67}]]
CallPacketに対する外部プログラムの 応答.
In[9]:= LinkRead[link]
Out[9]= 
外部プログラム1個に対して複数の Installを実行すると,Mathematicaはそのプログラムと複数のコネクションを開く.それぞれのコネクションは独立した LinkObjectとして働く.コンピュータシステムによっては,外部プログラムを複数呼び出すために外部プログラムのファイルをコピーする必要があるものもある.

外部プログラムの異なるインスタンスを特定する
:Begin:
:Function: addto
$CurrentLinkを addtoの引数にする.
:Pattern: addto[$CurrentLink, n_Integer]
:Arguments: n
:ArgumentTypes: Integer
:ReturnType: Integer
:End:
プログラムの開始時に大域変数のcounterをゼロに設定する.
int counter = 0;
int addto(int n) 
counter += n;
return counter;

addtoを含んでいる外部プログラムのインスタンスをインストールする.
In[10]:= ct1 = Install["addtoprog"]
Out[10]= 
別のインスタンスをインストールする.
In[11]:= ct2 = Install["addtoprog"]
Out[11]= 
外部プログラムの最初のインスタンスのcounterに10を足す.
In[12]:= addto[ct1, 10]
Out[12]= 
外部プログラムの2番目のインスタンスのcounterに15を足す.
In[13]:= addto[ct2, 15]
Out[13]= 
最初のプログラムのインスタンスに働きかける.
In[14]:= addto[ct1, 20]
Out[14]= 
外部プログラムにその状態を管理させて,異なる状態の異なるインスタンスを利用することもできる. $CurrentLinkはプログラムのそれぞれのインスタンスを示している.
$CurrentLinkの値は,プログラムが最初にインストールされるときと同様,プログラムのインスタンスが呼ばれるたびに一時的に設定される.

Mathematicaが評価すべき文字列を送信する
MathLinkコネクションの双方向性は, Mathematicaに外部プログラムの呼出しを可能にするばかりでなく,外部プログラムにMathematicaを呼び出させることを可能にする.
最も簡単に説明すると, MathLink関数MLEvaluateString()で文字列を Mathematicaに送信することができる. Mathematicaはその文字列を評価し,文字列が指定する作用を生成するが,その評価の結果は外部関数へは戻らない.
戻り値を得るには, EvaluatePacketを明示的に Mathematicaに送信して,戻ってくる ReturnPacketの中身を読む必要がある.
...
EvaluatePacketを開始する.
MLPutFunction(stdlink, "EvaluatePacket", 1);
Factorial[7]もしくは 7!の式を構成 する.
MLPutFunction(stdlink, "Factorial", 1);
MLPutInteger(stdlink, 7);
パケットの構成終了を示す.
MLEndPacket(stdlink);
ReturnPacketが返っていることを チェック.
MLCheckFunction(stdlink, "ReturnPacket", &n);
パケットから 7!の結果(整数)を取り 出す.
MLGetInteger(stdlink, &ans);
...

パケットを Mathematicaへ送信する
EvaluatePacket[input]を Mathematicaに送信すると、それに対して一般にたくさんのパケットが生成されるが、最後のパケットはReturnPacket[output]になる。前もって構造を知ることのできないパケットや式の列を扱う方法については 2.13.12 で解説する。
|