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としたら,正常に動作するようになった.