外部プログラム内からWolframシステムを呼び出す

外部プログラム内からWolframシステムを呼び出すためにはWSTP (Wolfram Symbolic Transfer Protocol)の一般的な多くの機能を利用する必要がある.まず最初は,WolframシステムとのWSTP接続を確立することである.
Wolfram言語から呼出し可能な外部プログラムを作成するのにWSTPテンプレートを利用した場合は,WSTP接続を確立するためのソースコードが自動的に作成され,外部プログラムは単にWSMain(argc,argv)を呼び出すだけでよい.しかし,一般に,WSTP接続を確立するには関数を何個か呼び出す必要がある.
WSENV WSInitialize(0)
WSTPライブラリ関数を初期化する
WSLINK WSOpenArgcArgv(WSENV env,int argc,char**argv,int*errno)
argv 配列からパラメータを取って,WSTP接続を開く
WSLINK WSOpenString(WSENV env,char*string,int*errno)
文字列1つからパラメータを取って,WSTP接続を開く
int WSActivate(WSLINK link)
WSTP接続を活性化し,他端のプログラムが応答するのを待つ
void WSClose(WSLINK link)
WSTP接続を閉じる
void WSDeinitialize(WSENV env)
WSTPライブラリ関数を終了する
WSTP接続の開閉
WSTPの標準ヘッダファイルを含む:
#include "wstp.h"
int main(int argc, char *argv[]) {
   WSENV env;
WSLINK link;
int errno;
WSTPライブラリ関数を初期化する:
   env = WSInitialize(0);
WSTP接続を開く.メインプログラムに与えられた引数を使う:
   link = WSOpenArgcArgv(env, argc, argv, &errno);
接続を活性化し,もう一方のプログラムが応答するのを待つ:
   WSActivate(link);
   ...
}
WSOpenArgcArgv()に渡すargvは,プログラムを開始させたときにmain()に渡されるargvが直接使われることがほとんどである.
argv中の要素は,Wolfram言語関数のLinkLaunchLinkCreateLinkConnectで使用する引数やオプションを表す文字列である.
"-linklaunch"
LinkLaunch["name"]のように作用する
"-linkcreate"
LinkCreate["name"]のように作用する
"-linkconnect"
LinkConnect["name"]のように作用する
"-linkname","name"
使用する名前を与える
"-linkprotocol","protocol"
使用するリンクプロトコル((TCPIPPipes等)を与える
WSOpenArgcArgv()に渡す配列argvに設定可能な要素
WSOpenArgcArgv()の代りに,引数をスペース文字で区切って連結した1つの文字列として受け取るWSOpenString()を利用することもできる.
Wolfram言語カーネルとのWSTP接続を開いたあとは,標準のWSTP関数を使ってデータが交換できるようになる.
int WSEndPacket(WSLINK link)
パケットの最後を示す
int WSNextPacket(WSLINK link)
次のパケットの頭部を見付ける
int WSNewPacket(WSLINK link)
現行のパケットの最後までスキップする
Wolfram言語カーネルと通信するためによく使う関数
WSPutFunction()その他でパケットを全部送り終えたら,WSEndPacket()を呼んで,WSTPと同期,調和を取る必要がある.
Wolfram言語カーネルと直に通信する外部プログラムを書く第1の目的は,カーネルが生成するさまざまな種類のパケットを処理することである.
関数WSNextPacket()はカーネルからくる次のパケットの頭部を見付け,パケットの種類を表す定数を返す.
Wolfram言語パケット
定数
ReturnPacket[expr]RETURNPKT
計算の結果
ReturnTextPacket["string"]RETURNTEXTPKT
結果のテキスト形式
InputNamePacket["name"]INPUTNAMEPKT
入力行の名前
OutputNamePacket["name"]OUTPUTNAMEPKT
出力行の名前
TextPacket["string"]TEXTPKT
Printのような関数が出したテキスト出力
MessagePacket[symb,"tag"]MESSAGEPKT
Wolfram言語が生成したメッセージ
InputPacket["prompt"]INPUTPKT
Input関数への応答を要求する
CallPacket[i,list]CALLPKT
外部関数の呼出しを要求する
WSNextPacket()が認識するパケットの一部
エラーが発生するか,ReturnPacketが見付かるまで,リンクからデータを読み続ける:
while ((p = WSNextPacket(link)) && p != RETURNPKT)
WSNewPacket(link);
Wolframシステムの完全なフロントエンドを書く場合は,カーネルが生成するあらゆる種類のパケットを処理する必要がある.WSNextPacket()が返す値に応じて適当にswitchを書けば問題ない.
WSTPデベロッパーキットには,簡単だが完全なフロントエンドのソースコードがいくつか入っている.
int WSReady(WSLINK link)
リンク上に読出しを待っているデータがあるかどうかをチェックする
int WSReadyParallel (WSENV e, WSLINK *links, int n, mltimeval t)
リンクのリストから読み込まれるデータがあるかどうかを並列にテストする
int WSFlush(WSLINK link)
リンクに書き出されるのを待っているデータを保持するバッファをフラッシュする
リンク上のデータの流れ
フロントエンドのような,より洗練された外部プログラムでは,Wolframシステムが送ってくるデータを待つ間でも,何等かのオペレーションを実行する必要がある場合もある.WSNextPacket()のような標準WSTPライブラリ関数を呼び出すと,プログラムはその関数が必要とするすべてのデータが得られるまで実行をブロックしてしまう.
WSReady()を繰り返し呼び,WSReady()0を返さなくなった時点でWSNextPacket()のような関数を呼ぶようにすれば,ブロックするのを避けることができる.WSReady()はWolfram言語関数LinkReadyQと類似の関数である.
WSTPが,送信が指令されたデータをバッファリングする場合もある.必要なデータを確実に送信するためにはWSFlush()を使う.その後はWSReady()を呼び,返ってくるデータを待つのみである.