C언어에서 Tcl의 인터프리터와 API사용하기

admin의 아바타

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