Welch, Jones, and HobbsのPractical Programming in Tcl and Tkの第47章には,C言語でTclを拡張する方法が説明されている.
Example 47-2にはバグがあり,古い書き方が残っている.
interp->result = "Usage: random ?range?";
のように直接Tcl_interpのフィールドを操作するのではなく,本文中にあるように
Tcl_SetResult(interp, "Usage: random ?range?", TCL_STATIC);
とした方が安全.
文字列はbufferという名前で宣言しているので,bufは誤り.
リンクオプションは,-bundleでも-dylibでもよい.tclのソースのmacosx/READMEには-dylibのみunload可能とあるが,どうしたらよいかは分からない.
MacPortsのTclでは,libtcl.dylibにリンクするが,Mac OS X添付のTclでは,-framework Tcl -framework Systemが使える.自分でソースからコンパイルするときは,ソースのmacosxで./configureのオプションに--enable-frameworkを付け加える.
ところで,Leopard添付のtclshでは共有ライブラリの読み込みができたが,MacPortsのtcl-8.5.6ではRandom_SafeInit, Random_SafeUnload, Random_Unloadをソースに定義していないとエラーとなる.
Random_SafeInit(Tcl_Interp *interp) {
return Random_Init(interp);
}
int
Random_Unload(Tcl_Interp *interp, int flags) {
return TCL_OK;
}
int
Random_SafeUnload(Tcl_Interp *interp, int flags) {
return TCL_OK;
}
Ubuntuでやってみたが,これらは必要ないので,MacでTcl-8.5を使うときに発生する問題のようだ.
MacPortsのtclsh(tclを+universalでインストール)では,ロード後コマンドを実行したら,mallocでエラーが出た.ActiveTclや/usr/localにインストールしたものは大丈夫だった.MacPortsでも+universal +threadsとしたら,正常に動作するようになった.