본문으로 바로가기

우선 소스를 보여 드리면서 소개를 하고 싶습니다. 아래의 소스는 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 보면 나와 있는데 이걸 몰라서..한참 헤멨다는... 
다들 아시겠지만..혹시 첨 시작하시는 분들중 저같은 분들이 계실까봐..올립니다..