우선 소스를 보여 드리면서 소개를 하고 싶습니다. 아래의 소스는 C언어의 프로그램 안에 Tcl의 API를 사용한 예를 소개하고 있습니다. 그럼 간단한 예제로 시작합니다.
#include <stdio.h>
#include <tcl.h>
int main(int argc, char *argv[])
{
Tcl_Interp *interp;
char buf[256];
interp = Tcl_CreateInterp();
strcpy(buf, "expr 3+5");
Tcl_Eval(interp, buf);
fprintf(stdout, "3+5 = %s\n", Tcl_GetStringResult(interp));
return 0;
}
컴파일을 해보고 싶으신 분들을 위해 설명은 뒤로 미루고 컴파일을 해보도록 하겠습니다. 참고로 볼랜드 C++로 컴파일을 하기 위해서는 제공되는 tcl84.dll을 볼랜드용 lib로 바꿔줄 필요가 있습니다. 우선 Tcl/Tk가 설치된 디렉토리의 bin 디렉토리에서
implib -a tcl84bcc.lib tcl84.dll
implib -a tk84bcc.lib tk84.dll
위와 같이 변경 후 Tcl/Tk가 설치된 디렉토리의 lib로 복사를 해줍니다. 이제 각 컴파일러별로 아래와 같이 컴파일을 해주시면 됩니다.
Borland C++
bcc32 -I"c:\tcl\include" -L"c:\tcl\lib" demo.c tcl84bcc.lib
gcc
gcc -o demo -I/usr/local/include -L/usr/local/lib demo.c -ltcl8.4 -lm
Visual C++
cl -o demo.exe -I"C:\Tcl\include" demo.c "C:\Tcl\lib\tcl84.lib" "C:\Tcl\lib\tk84.lib"
실행결과는 아래와 같이 나올 것입니다.
위의 소스에서 주의 깊게 볼 필요가 있는 것이 Tcl_Eval이라는 API입니다. 이 API는 임의의 Tcl, Tk 스크립트를 실행시켜 주는 역할을 하고 있습니다. 이 API를 사용하면 간단하게 tclsh를 만들 수가 있습니다. 아래의 소스를 보도록 하겠습니다.
#include <stdio.h>
#include <tcl.h>
#define BUFSIZE 1024
int main(int argc, char *argv[])
{
Tcl_Interp* interp;
char buf[BUFSIZE];
interp = Tcl_CreateInterp();
Tcl_FindExecutable(argv[0]);
if(Tcl_Init(interp) != TCL_OK) {
fprintf(stderr, "Tcl initialization error: %s\n",
Tcl_GetStringResult(interp));
return 1;
}
while(1){
fprintf(stdout, "input tcl command: ");
if(! fgets(buf, BUFSIZE, stdin)) break;
if(Tcl_Eval(interp, buf) == TCL_OK) {
fprintf(stdout, "%s\n", Tcl_GetStringResult(interp));
} else {
fprintf(stdout, "ERROR! %s\n", Tcl_GetStringResult(interp));
}
}
fprintf(stdout, "good bye.\n");
Tcl_DeleteInterp(interp);
return 0;
}
Tcl_Init는 Tcl/Tk를 설치했을 때 tcl8.4 디렉토리에 있는 init.tcl을 source로 하고 있는 API입니다. 즉, 실행환경에 관련된 각종의 글로벌변수를 세팅하거나 하는 데 사용됩니다. 위의 예에서는 필요하지 않으므로 꼭 부를 필요는 없습니다. Tcl_Eval은 Tcl 커맨드를 실행한 결과가 정상이면 TCL_OK를 리턴하고, 에러이면 TCL_ERROR를 리턴합니다. 정상적으로 실행된 커맨드의 경우는 Tcl_GetStringResult라고 하는 API로 결과를 얻을 수 있습니다.
#include <stdio.h>
#include <tcl.h>
#define BUFSIZE 1024
int main(int argc, char *argv[])
{
Tcl_Interp *interp;
char *regexp;
char buf[BUFSIZE];
if(argc < 2){
fprintf(stdout, "usage: %s regexp < textfile\n", argv[0]);
return 1;
}
regexp = argv[1];
interp = Tcl_CreateInterp();
while(fgets(buf, BUFSIZE, stdin)){
switch(Tcl_RegExpMatch(interp, buf, regexp)){
case -1:
fprintf(stdout, "Regular expression syntax error: %s\n", regexp);
goto eee;
case 1:
fprintf(stdout, "%s", buf);
break;
default:
break;
}
}
eee:
return 0;
}
위의 프로그램은 이른바 유닉스에서의 grep과 같은 프로그램입니다. 소스 중에서 Tcl_RegExpMatch는 본래의 Tcl언어의 regexp 커맨드를 만드는 데 사용되는 API로, 이것을 사용하면 정규표현패턴 조합이라고 하는 복잡한 처리의 기능을 쉽게 할 수 있습니다. 이와 같이 Tcl API는 Tcl언어를 떠나 순수한 C언어의 라이브러리로써도 사용가능한 훌륭한 라이브러리입니다.
C언어에 Tk로 GUI를 제작하는 방법
#include <stdio.h>
#include <tcl.h>
#include <tk.h>
int main(int argc, char *argv[])
{
Tcl_Interp *interp;
char buf[256];
interp = Tcl_CreateInterp();
Tcl_FindExecutable(argv[0]);
if(Tcl_Init(interp) != TCL_OK) {
fprintf(stderr, "Tcl initialization error: %s\n",
Tcl_GetStringResult(interp));
return 1;
}
if(Tk_Init(interp) != TCL_OK) {
fprintf(stderr, "Tk initialization error: %s\n",
Tcl_GetStringResult(interp));
return 1;
}
strcpy(buf, "label .laba -text {Hello, World} -rel groove -bd 3\n\
button .cmda -text {Quit} -command exit\n\
pack .laba .cmda");
Tcl_Eval(interp, buf);
Tk_MainLoop();
return 0;
}
위의 소스에는 Tk_Init와 Tk_MainLoop이라고 하는 Tk API가 나와 있습니다. 이러한 사용 방법은 C에서의 Tk GUI프로그래밍의 정석이라 생각하고 이대로 Tk GUI프로그래밍을 하시면 됩니다.
아래는 easywork 회원님이 작성하신 팁입니다.
tcl 을 처음 접해보고..거기다..
볼랜드 씨로 컴파일 하실려는 분들을 위해 짧은 글 남깁니다..^^
여기 강좌 에는 생략이 되어 있던데요..
볼랜드 씨 컴파일러를 설치 하시고 몇가지 설정 파일을 만들어 주셔야 합니다..
볼랜드 씨가 설치된 디렉토리의 bin 디렉토리 안에
bcc32.cfg 파일과 ilink32.cfg 라는 두개의 파일을 만들어 주셔야 하구요
bcc32.cfg 안에는
-I"c:\Borland\Bcc55\include"
-L"c:\Borland\Bcc55\lib"
이런식으로 헤더파일하고 라이브러리 위치를 지정해 주셔야 하구요
ilink32.cfg 안에는
-L"c:\Borland\Bcc55\lib"
이런식으로 해주어야 하더라구요..
README 보면 나와 있는데 이걸 몰라서..한참 헤멨다는...
다들 아시겠지만..혹시 첨 시작하시는 분들중 저같은 분들이 계실까봐..올립니다..