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 に置く |
まずはじめに,標準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倍精度実数 |
プログラムにより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()はそれらを指定した固定のコードに変換する.
Unixモデルに立脚したCのランタイムライブラリを持つコンピュータシステムやコンパイラであれば,WSTPプログラムのメインプログラムとして,WSMain(argc,argv)を呼ぶだけのmain(argc,argv)があれば問題ない.
しかし,コンピュータシステムやコンパイラによっては違った形式のメインプログラムが必要になるものもある.main()中でWSMain()を呼ぶ前に必要な初期化を行うことも可能である.しかし,WSMain()を呼んだ後はWolfram言語につながったリンクが閉じられるまで,Wolfram言語からのリクエストに応答するという無限ループに入ってしまう.