Tcl APIのクセ
 ここではAPIに関して概して言えることをまとめてメモってみます。
  • サイズはint
    文字列の長さなどを指定したり受け取ったりするときに使う変数は、 Tcl APIでは全部が全部unsigned intでもlongでもsize_tでもなくintを使います。
  • 積極的にvoidを使っている
    APIがとくに重要な値を返さない場合は、そのAPIは必ずvoidになっています。 つまり、何かの値を返すAPIはできるだけその値をチェックするようにすべきです。
  • VarとVar2
    〜VarというAPIと〜Var2というAPIは全く同じ機能のAPIで、引数にTcl変数の名前を別々の方法でとるものです。例えば
      Tcl_GetVar(interp, varname, flags)
      Tcl_GetVar2(interp, varname1, varname2, flags)
    
    という2つのAPIは全く同じ機能ですが、例えばTcl変数 $scalorvalue の値を知りたいとき、
      Tcl_GetVar(interp, "scalorvalue", flags)
      Tcl_GetVar2(interp, "scalorvalue", NULL, flags)
    
    またTcl変数 $arrayelem(1) の値を知りたいとき、
      Tcl_GetVar(interp, "arrayelem(1)", flags)
      Tcl_GetVar2(interp, "arrayelem", "1", flags)
    
    のように使います。

最初のうちはいらないAPI
「Obj」という名前のついたAPIはたくさんありますが、 こいつらどもはTcl 8.0になって主にバイナリデータ(*1)を扱うために追加されたAPIです。 現在の8.1や8.2でも、 バイナリデータを全く扱わないならこれらは全く不要です。逆に、
  • バイナリデータを値として返すTclコマンドをつくる
  • バイナリデータを引数としてとるTclコマンドをつくる
  • マニュアルで勧められていないことはやりたくないんだもん
という場合は、これらを使うことは避けて通れません。 位置付けとしては、「Obj」とついたAPIには、必ずそのレッサーバージョン (バイナリデータでなくC言語型の文字列しか扱えない以外はほぼ同じ機能のAPI) が存在し、マニュアルではレッサーバージョンの使用はあまり勧めていません。 しかし、 「Obj」のつかないレッサーバージョンの方がプログラムは簡潔になることが多いので、 「Tclオブジェクト」を理解した後も、 バイナリを扱う、扱わないで適宜使い分けるとよいでしょう。
(*1)「バイナリデータ」とは、意味のあるデータの途中にNULL文字(0x00) が含まれている可能性のあるデータの意、逆に「C言語型の文字列」とは、 先頭から最初に現れるNULL文字までを意味のあるデータとみなすデータの意味です。 以後この説明では何度も出てきますが、全部そういう意味です。

また、Tcl APIのうち大きなグループを作っているファイルチャネルI/O (Tcl_OpenFileChannel、Tcl_ReadChars、Tcl_WriteCharsなど) のAPIどもは、最初のうちはばっさり無視してもOKです。 これらの代わりに普通C言語で使うFILE構造体を使うこともできますし、 どうしてもというなら "set fp [open filename r]" という文字列をC言語で作り、これを解釈実行することでファイルI/O を実現することもできます(おすすめはしませんが)。

これで、一気に覚えるAPIの数が減りましたね。 マニュアルの目次を見てゲンナリしていた方も少しやる気ドリンクになったかも?

なもなも top
(first uploaded 1999/03/12 last updated 2000/11/28 , Urano398 )