外部プログラム中で式を処理する
Wolfram言語の式はすべての種類のデータを扱うことができる,非常に一般的な方法を提供しているが,その式を外部プログラム中で利用したいこともあるだろう.しかし,Cのような言語は通常のWolfram言語の式を保持する直接的な方法がないが,Wolfram Symbolic Transfer Protocol (WSTP)ライブラリが提供するループバックリンクを利用すれば可能になる.ループバックリンクとは外部プログラム内部のローカルなWSTP接続で,そのリンクに式を書き込んで,あとでその式を読み戻すことが可能である.
WSLINKWSLoopbackOpen(stdenv,int*errno) | |
ループバックリンクを開く | |
voidWSClose(WSLINK link) | リンクを閉じる |
intWSTransferExpression(WSLINK dest,WSLINK src) | src から得た式を dest に置く |
...
wstp = WSLoopbackOpen(stdenv, &errno);
式Power[x,3]をリンクに置く:
WSPutFunction(wstp, "Power", 2);
WSPutSymbol(wstp, "x");
WSPutInteger32(wstp, 3);
...
WSGetFunction(wstp, &head, &n);
WSGetSymbol(wstp, &sname);
WSGetInteger32(wstp, &k);
...
WSClose(wstp);
...
WSPutFunction(wstp, "Factorial", 1);
WSPutInteger32(wstp, 21);
頭部FactorIntegerをWolfram言語に送信する:
WSPutFunction(stdlink, "FactorInteger", 1);
WSTransferExpression(stdlink, wstp);
普通は取り出した式はリンク上には残っていない.しかし,WSCreateMark()を使えば,リンク上の式のシーケンスの特定の位置にマークすることができる.WSTPが式を保存するときはいつもそのマークの後ろに保存させることができ,それを後で取り出すことができる.
WSMARKWSCreateMark(WSLINK link) | リンク上の式のシーケンスの現在地にマークを付ける |
WSSeekMark(WSLINK link,WSMARK mark,int n) | |
リンク上の特定のマークから n 式後ろに移動する | |
WSDestroyMark(WSLINK link,WSMARK mark) | リンク上のマークを破壊する |
...
WSPutInteger32(wstp, 45);
WSPutInteger32(wstp, 33);
WSPutInteger32(wstp, 76);
WSGetInteger32(wstp, &i);
mark = WSCreateMark(wstp);
WSGetInteger32(wstp, &i);
WSGetInteger32(wstp, &i);
WSSeekMark(wstp, mark, 0);
WSGetInteger32(wstp, &i);
WSDestroyMark(wstp, mark);
WSTPライブラリは,ループバックリンクの開閉が非常に効果的に行えるように実装されている.ひとつだけ頭に入れておくべきことは,あるリンク上にマークを生成すると,WSTPは,マークが破壊されるまで,その後リンクに置かれる式を記憶することである.
intWSGetNext(WSLINK link) | リンク上の次のオブジェクトのタイプを見付ける |
intWSGetArgCount(WSLINK link,int*n) | リンク上の関数の取る引数の個数を n に保管する |
intWSGetSymbol(WSLINK link,char**name) | シンボル名を取得する |
intWSGetInteger32(WSLINK link,int*i) | 機械サイズの整数を取得する |
intWSGetReal64(WSLINK link,double*x) | 機械サイズの浮動小数点数を取得する |
intWSGetString(WSLINK link,char**string) | 文字列を取得する |
switch(WSGetNext(wstp)) {
case WSTKFUNC:
WSGetArgCount(wstp, &n);
recurse for head
for (i = 0; i < n; i++) {
recurse for each argument
}
…
case WSTKSYM:
WSGetSymbol(wstp, &name);
…
case WSTKINT:
WSGetInteger32(wstp, &i);
…
}
WSGetNext()を使うことで,あらゆる式を読み込むプログラムを書くことは簡単になる.WSTPの動作に従い,関数の頭部と引数とは,リンク上の連続した式として現れ,それらを1個ずつ読み込むことができる.
関数の頭部がシンボルであることが分かったら,WSGetNext()の代りにWSGetFunction()を使うことができる.しかし,この場合,そのシンボル名を保持するために使ったメモリをWSReleaseSymbol()を呼び出して解放することを忘れないこと.
intWSPutNext(WSLINK link,int type) | 指定した型のオブジェクトをリンクへ置く準備をする |
intWSPutArgCount(WSLINK link,int n) | 合成関数の引数の個数を与える |
intWSPutSymbol(WSLINK link,char*name) | |
リンクにシンボル名を置く | |
intWSPutInteger32(WSLINK link,int i) | リンクに機械サイズの整数を置く |
intWSPutReal64(WSLINK link,double x) | リンクに機械サイズの浮動小数点数を置く |
intWSPutString(WSLINK link,char*string) | |
リンクに文字列を置く |