WSTPプログラムの移植性

Wolfram Symbolic Transfer Protocol (WSTP)のWolfram言語側はすべてのコンピュータシステムで全く変更なしで動く.しかし,コンピュータシステムによって外部プログラムに違いがあるのは避けることができない.
コンピュータシステムが異なると実行可能なバイナリも異なる.そのため,Install["prog"]を呼び出す場合,prog がそれを利用しようとするコンピュータ上で実行可能であることを確認する必要がある.
Install["file"]
file の直接実行を試みる
Install["file",LinkProtocol->"type"]
低レベルのデータ転送を指定したプロトコルで行う
$SystemID
使用中のコンピュータシステムのタイプを示す
Install["dir"]
dir/$SystemID/dir の名前のファイルの実行を試みる
異なるコンピュータシステムにプログラムをインストールする
Wolfram言語は,もし prog が通常のファイルであれば,Install["prog"]は単にそのファイルの実行を試みる.prog がディレクトリであったらWolfram言語はそのディレクトリ中の名前が$SystemIDに一致するサブディレクトリを探し,そのサブディレクトリ中の prog の名前のファイルの実行を試みる.
mcc -o prog
コンパイルしたコードを現行のディレクトリ中の prog ファイルに置く
mcc -xo prog
コンパイルしたコードを prog/$SystemID/prog に置く
外部プログラムをコンパイルする代表的なUnixコマンド
外部プログラムの実行可能なバイナリがコンピュータシステムによって異なるとはいっても,Cで書いたソースコードは本質的に同じという場合がある.
しかし,Cのソースコードの移植性を高めるためには,気を付けるべき点もある.
まずはじめに,標準Cには含まれない機能,特殊なシステムで提供されているCのランタイムライブラリ等は利用すべきではない.さらに,セグメント化した,もしくは,その他の特殊なメモリモデルを扱うことを避けるようにすべきである.
インクルードファイルwstp.hでは,WSTPライブラリのすべての関数について標準Cのプロトタイプ宣言がなされている.
WSPutInteger32()WSGetInteger32()
int型のCに対応する整数.32ビット
WSPutInteger16()WSGetInteger16()
short型の整数.通常,16ビット
WSPutInteger64()WSGetInteger64()
64ビットの整数
WSPutReal64()WSGetReal64()
IEEE倍精度実数.C言語のdouble型に対応
WSPutReal32()WSGetReal32()
IEEE単精度実数.C言語のfloat型に対応
WSPutReal128()WSGetReal128()
IEEE4倍精度実数
C特有の型を扱うWSTP関数
WSTPライブラリ関数を移植性を保って呼び出すには,ライブラリが使っているのと同じ型で利用することが重要である.
プログラムによりWSTPライブラリ関数の引数型にマッチされる場合は,コンピュータシステム間のCタイプの差分を心配する必要はない.WSTPはCタイプを各プラットフォームにとって適した大きさに自動的に変換する.また,WSTPはプラットフォーム間で数を正確に転送するために必要なだけのバイトをスワップし,できる限り精度を落とさないよう,浮動小数点数のフォーマットを変換する.
WSPutString(stdlink,char*s)
ヌルで終了するC文字列を送信する
WSPutUnicodeString(stdlink,unsigned short*s,int n)
16ビットUCS-2 Unicode文字で符号化された文字列を送信する
WSPutByteString(stdlink,unsigned char*s,int n)
8ビット文字コードのみを含む文字列を送信する
WSPutUTF8String(stdlink, const unsigned char*s,int n)
UTF-8 Unicode符号化方式の文字列を送信する
WSPutUTF16String(stdlink, const unsigned short*s,int n)
UTF-16 Unicode符号化方式の文字列を送信する
WSPutUTF32String(stdlink, const unsigned int*s,int n)
UTF-32 Unicode符号化方式の文字列を送信する
WSGetString(stdlink,char**s)
ヌルで終了するC文字列を受信する
WSGetUnicodeString(stdlink,unsigned short**s,long*n)
16ビットUCS-2 Unicode文字で符号化された文字列を受信する
WSGetByteString(stdlink,unsigned char**s,long*n,long spec)
8ビット文字コードのみを含む文字列を受信する, 16ビットの文字はすべてspec をそのコードに用いる
WSGetUTF8String(stdlink, const unsigned char**s,int*m,int*n)
UTF-8 Unicode符号化方式の文字列を受信する
WSGetUTF16String(stdlink, const unsigned short**s,int*m,int*n)
UTF-16 Unicode符号化方式の文字列を受信する
WSGetUTF32String(stdlink, const unsigned int**s,int*n)
UTF-32 Unicode符号化方式の文字列を受信する
一般的な文字列を処理する
普通のCプログラムでは,文字列は通常のASCII文字だけからなることが普通である.しかしWolfram言語ではすべての種類の特殊文字を含む文字列を扱うことができる.それらの文字は「外部文字コードの使用」で説明した文字コードUnicodeでWolfram言語中で表現されている.
C言語のchar*文字列中のひとつひとつの文字は,通常8ビットで保持できる文字である.しかし,UCS-2で符号化された文字列では16ビット全部を使う.結果として,WSPutUnicodeString()WSGetUnicodeString()ではunsignedshort型の整数配列を用いて文字列を表現する.UTF-16で符号化された文字列およびそれに対応する関数WSPutUTF16String()WSGetUTF16String()についても同じことが言える.
UTF-32でコード化された文字列には,それぞれの文字に対して32ビット必要であり,対応する関数のWSPutUTF32String()WSGetUTF32String()unsigned int整数の配列を扱う.
もし,プログラムに特殊文字を扱う必要がなかったら,WSPutByteString()WSGetByteString()を使うことが便利だろう.それらの関数はすべての文字を直接8ビット文字コードで表現する.Wolfram言語から特殊文字が送信されてきたら,WSGetByteString()はそれらを指定した固定のコードに変換する.
main()はコンピュータシステムに応じて異なる場合がある.
移植可能なWSTPプログラムを書くための注意点
Unixモデルに立脚したCのランタイムライブラリを持つコンピュータシステムやコンパイラであれば,WSTPプログラムのメインプログラムとして,WSMain(argc,argv)を呼ぶだけのmain(argc,argv)があれば問題ない.
しかし,コンピュータシステムやコンパイラによっては違った形式のメインプログラムが必要になるものもある.main()中でWSMain()を呼ぶ前に必要な初期化を行うことも可能である.しかし,WSMain()を呼んだ後はWolfram言語につながったリンクが閉じられるまで,Wolfram言語からのリクエストに応答するという無限ループに入ってしまう.