【コラム】
第13回はTcl/Tkを使ってみましょう。Tcl/Tkは、スクリプト言語のTclと、そのGUI拡張であるTkとによって構成されています。まずはTclのみを使ったHello Worldを作成し、その後Tcl/TkのGUIのHello Worldを作成していきます。
リスト1は、Tclのputsを使ったHello Worldです。このようにTclスクリプトでは、インタプリタとしてtclshを使います。putsでは、改行は自動的に付加されます。Tclの文字列は、{ }またはダブルクォートで囲みます。ダブルクォートの場合は\nなどのエスケープ文字が解釈されますが、{ }の場合はそのままの文字列と解釈されます。
#!/usr/bin/tclsh ← Tclのインタプリタであるtclshを指定
puts {Hello World} ← putsで文字列を出力(改行は自動)
Tclのスクリプトは、ほかのスクリプトと同様、実行例1のように実行属性を付ければ実行できます。
$ chmod +x tcl_puts ← Tclスクリプトに実行属性を付ける
$ ./tcl_puts ← Tclスクリプトを実行
Hello World ← 確かにHello Worldと表示される
$ ← シェルのプロンプトに戻る
putsは改行コードを付加しますが、-nonewlineオプションを付けると、改行の付加を抑制できます。そこで、リスト2のように、自分で改行コードを記述する方法も考えられます。ここでは文字列はダブルクォートで囲む必要があります。
#!/usr/bin/tclsh
puts -nonewline "Hello World\n" ← putsに任せず、自分で改行コードを記述する
Tclでは、printf形式の書式指定はformatを使って行います(リスト3)。formatは、sprintfに相当する動作を行い、結果の文字列を出力するため、これを[ ]で取り込んで、putsなどの引数として利用します。ここでは、format側で改行を付加し、putsの方には-nonewlineオプションを付けています。
#!/usr/bin/tclsh
puts -nonewline [format "%s\n" {Hello World}] ← formatで書式指定しputsで出力
TclからOSのコマンドを呼び出すには、リスト4のようにexecを使います。このexecは、シェルスクリプトのexecとは違って、OSのコマンドを呼び出したあとはTclに制御が戻ってきます。また、execの出力を標準出力に出力するには、明示的に「>@ stdout」というリダイレクトを行う必要があります。
#!/usr/bin/tclsh
exec echo {Hello World} >@ stdout ← OS上のechoコマンドを呼び出す
Tclのライブラリは、C言語から呼び出して使うこともできます。標準出力に文字列を出力するには、リスト5のように、必要な前処理のあと、Tcl_Write()関数を使って出力します。
#include <tcl.h> ← Tclのヘッダが必要
int
main()
{
Tcl_Interp *interp; ← Tclのインタプリタへのポインタ
Tcl_Channel channel; ← Tclの入出力チャンネル
interp = Tcl_CreateInterp(); ← インタプリタを作成
channel = Tcl_GetStdChannel(TCL_STDOUT); ← 標準出力のチャンネルを取得
Tcl_Write(channel, "Hello World\n", 12); ← 標準出力に文字列を出力
return 0;
}
このプログラムはTclのライブラリとリンクするため、実行例1のように「-ltcl」を追加してコンパイルします。
$ gcc -O2 -o tcl_c_write tcl_c_write.c -ltcl ← 「-ltcl」を追加してコンパイル
Tclスクリプトの文字列を解釈して実行する、Tcl_Eval()という関数があります。このTcl_Eval()を呼び出すことによって、C言語からTclスクリプトを実行することも可能です(リスト6)。ここでは、TclスクリプトがC言語のソース中に文字列として埋め込まれています。なお、このプログラムも前項の実行例1と同様に、「-ltcl」を追加してコンパイルします。
#include <tcl.h> ← Tclのヘッダが必要
int
main()
{
Tcl_Interp *interp; ← Tclのインタプリタへのポインタ
interp = Tcl_CreateInterp(); ← インタプリタを作成
Tcl_Init(interp); ← Tclを初期化
Tcl_Eval( ← Tcl_Eval()でTclスクリプトを実行
interp, ← インタプリタを指定
"puts {Hello World}\n" ← Tclスクリプトの文字列を引数とする
);
return 0;
}
次は、TclにTkを加えた、Tcl/TkのGUIのプログラムです。 Tcl/Tkのスクリプトでは、インタプリタとして、tclshの代わりにwishを用います。Hello Worldのプログラムは、リスト7のようにlabelを使って記述します。実行すると図1のウィンドウが表示されます。
#!/usr/bin/wish ← インタプリタはwish
label .hello -text {Hello World} -width 22 -height 5 ← ラベルを作成
pack .hello ← ラベルを配置
|
|
図1 Tcl/TkのHello World |
Tcl/Tkのwish用スクリプトも、C言語からTcl_Eval()を呼び出すことによって実行することができます(リスト8)。ただし、Tcl単独のスクリプトを実行する場合とは違って、Tk_Init()とTk_MainLoop()の呼び出しが必要です。なお、Tcl_Eval()の引数のTcl/Tkのスクリプト文字列は、2行に分けて記述していますが、コンパイル時には1つの文字列として連結されることに注意してください。
#include <tcl.h> ← Tclのヘッダが必要
#include <tk.h> ← Tkのヘッダが必要
int
main()
{
Tcl_Interp *interp; ← Tclのインタプリタへのポインタ
interp = Tcl_CreateInterp(); ← インタプリタを作成
Tcl_Init(interp); ← Tclを初期化
Tk_Init(interp); ← Tkを初期化
Tcl_Eval( ← Tcl_Eval()でTcl/Tkのスクリプトを実行
interp, ← インタプリタを指定
"label .hello -text {Hello World} -width 22 -height 5\n"
"pack .hello\n" ←↑ Tcl/Tkのスクリプト文字列(2行で1つの引数)
);
Tk_MainLoop(); ← メインループを実行
return 0;
}
このプログラムは、TkとTclのライブラリとリンクするため、実行例2のように「-ltk -ltcl」を追加してコンパイルします。実行時の画面は、前掲の図1と同じです。
$ gcc -O2 -o tk_c_label tk_c_label.c -ltk -ltcl ← 「-ltk -ltcl」を追加
| 理研、脳・脊髄形成に必要な神経板湾曲の仕組みを解明 [20:16 5/25] |
| 京大、「慢性閉塞性肺疾患」患者の労作時呼吸困難は鍼治療が有効と実証 [20:08 5/25] |
| 120Hz SHVカメラ用イメージセンサーを使った撮像装置 - SHVフルスペック化へ [18:10 5/25] |
| 京大、視覚による物体認知は前頭前野からのトップダウン信号が重要と確認 [17:45 5/25] |
| 製品数の拡大だけでなくBCPの展開なども含めた総合力で事業の強化を図るTI [17:25 5/25] |
|
【連載】これだけは要チェック! TOEIC(R)単語帳 第108回 今回のお題は…「issue」 [20:00 5/27] キャリア |
|
TVアニメ『ペルソナ4』、新規カットを加えた再編集版を劇場でイベント上映 [20:00 5/27] ホビー |
|
[9nine]制服姿見納め? セーラー服で登場も川島海荷「4人はコスプレ」 [19:15 5/27] エンタメ |
|
「NO.6」4巻は書き下ろしドラマCD付、木乃のサイン会も [18:49 5/27] ホビー |
|
[今週の新刊]マンガ大賞3回ノミネート「アイアムアヒーロー」 カープ愛「球場ラヴァーズ」も [18:33 5/27] ホビー |
4つの診断で、自分の適性を見つめなおそう!
働くこと・挑戦し続けることへの思いを綴ったインタビュー
あなたにピッタリのアドバイスを読むことができます。
転職に必要な情報が収集できます
企業からアプローチのメッセージが届きます。