내용 목차
본 장은 API 사용 프로그램 예제를 설명한다.
다음과 같은 함수를 동적 모듈로 컴파일하여 my_function.sl을 생성한다.
#include <tdlcall.h> /* tdlcall로 호출되어질 함수 */ long my_function(void *args) { long urcode; urcode = (long)time (NULL); strcpy((char*)args, "my_function"); return urcode; }
이 모듈을 사용하는 측에서는 다음과 같이 사용한다.
/* TDL 관련 함수들을 사용하기 위하여 반드시 include 필요 */ #include <tdlcall.h> int retval; char data[256]; long urcode; /* tdlcall 함수 호출 : TDL Version 1 */ retval = tdlcall("my_function", (void*)data, &urcode, TDL_NOFLAGS); if (retval != TDL_OK) { printf("tdlcall(%s) = %d, with err[%s]\n", "my_function", retval, tdlerror(retval)); } else { /* my_function 함수에서 전달받은 값 출력 */ printf("tdlcall(%s) = %d, urcode = %#08x, data = %s\n","my_function", retval, urcode, data); }
본 절에서는 C++에서 TDL을 사용하는 인터페이스를 설명한다.
다음과 같은 함수를 동적 모듈로 컴파일하여 dlib.so를 생성한다.
dlib.h
/* dlib.h */ namespace TmaxSoft { class Airplain { private: int state; public: Airplain(); virtual char *Start(); virtual char *Stop(); virtual int getState(); }; } class Car { private: int state; public: Car(); virtual char *Start(); virtual char *Stop(); virtual int getState(); };
dlib.cpp
/* dlib.cpp */ #include <string.h> #include <usrinc/tdlcall.h> #include "dlib.h" long tdlcreate_cb(const char *snm, const char *cnm, void *args, void **obj) { if (0) { } else if (!strcmp(snm, "TmaxSoft") && !strcmp(cnm, "Airplain")) { *obj = (void *) new TmaxSoft::Airplain(); if (*obj != NULL) return 1; else return -1; } else if (!strcmp(snm, "") && !strcmp(cnm, "Car")) { *obj = (void *) new Car(); if (*obj != NULL) return 1; else return -1; } return -1; } long tdldestroy_cb(const char *snm, const char *cnm, void *args, void *obj) { if (0) { } else if (!strcmp(snm, "TmaxSoft") && !strcmp(cnm, "Airplain")) { delete (TmaxSoft::Airplain *)obj; return 1; } else if (!strcmp(snm, "") && !strcmp(cnm, "Car")) { delete (Car *)obj; return 1; } return -1; } TmaxSoft::Airplain::Airplain() { state = 0; } char* TmaxSoft::Airplain::Start() { state = 2; return (char *)"TmaxSoft::Airplain::Start "; } char* TmaxSoft::Airplain::Stop() { state = 1; return (char *)"TmaxSoft::Airplain::Stop "; } int TmaxSoft::Airplain::getState() { return state; } Car::Car() { state = 0; } char* Car::Start() { state = 2; return (char *)"Car::Start "; } char* Car::Stop() { state = 1; return (char *)"Car::Stop "; } int Car::getState() { return state; }
이 모듈을 사용하는 측에서는 다음과 같이 사용한다.
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <usrinc/tdlcall.h> #include "dlib.h" int main(int argc, char *argv[]) { int ret; long urcode; TmaxSoft::Airplain *obj; if ((ret = tdlcreate("dlib", "TmaxSoft", "Airplain", NULL, (void **)&obj, &urcode, 0)) < 0) { printf("obj is NULL\n"); printf("%s\n", tdlerror(ret)); } else { printf("obj %s\n", obj->Start()); printf("obj %s\n", obj->Stop()); printf("obj %d\n", obj->getState()); } return 0; }
클래스는 nm에서 심볼을 정확하게 확인하기 어렵기 때문에 tdlinit, tdlupdate의 경우에는 반드시 exp 파일이 필요하다. export 파일의 사용 방법은 다음과 같다.
VERSION=1, 2, 3으로 설정된 경우에는 함수명을 한 줄에 하나씩 나열했지만, VERSION=4로 설정한 경우에는 클래스명을 한 줄에 하나씩 나열한다. 만약 네임스페이스가 적용된 경우에는 namespace::classname 형태로 한 줄에 하나씩 나열한다.
# libuser.so foo bar # libuserclass.so classCar classBus tmaxsoft::classCar tmaxsoft::classBus tibero::myClass
#include <stdio.h> #include <stdlib.h> #include <usrinc/atmi.h> #include <usrinc/tmaxapi.h> #include <usrinc/tdlcall.h> TSVC1(TPSVCINFO *msg) { int i; int n; long urcode; char *rcvbuf; long rcvlen; int ret; printf("TSVC1 service is started!\n"); /* tdlstart 호출하여 명시적 버전 보호 시작 */ tdlstart(); n = tdlcall("myfunction1", (void*)msg->data, &urcode, 0); if (n != TDL_OK) { printf("tdlcall(myfunction1) = %d, with err[%s]\n", n, tdlerror(n)); } else { printf("tdlcall(myfunction1) = %d, urcode = %#08x\n", n, urcode); } sprintf((char *)msg->data, "[TSVC1]tdlcall(myfunction1)=%d", urcode); if ((rcvbuf = (char *)tpalloc("STRING", NULL, 0)) == NULL) { printf("recvbuf alloc failed !\n"); tpreturn (TPFAIL, -1, NULL, 0, 0); } if(tpcall("TSVC2", rcvbuf, 0, &rcvbuf, &rcvlen, 0)==-1) { printf("Can't send request to service TSVC2[%d]\n", tperrno); tpfree((char *)rcvbuf); tpreturn (TPFAIL, -1, NULL, 0, 0); } /* tdlend 호출하여 명시적 버전 보호 종료 */ tdlend(); strcat((char *)msg->data, rcvbuf); msg->len = strlen((char *)msg->data); tpreturn(TPSUCCESS,0,(char *)msg->data, msg->len, 0); }
본 절에서는 TDL 환경설정 중 기존의 MAXMODULES 변경 기능과 tdlsync와 tdlinit을 이용한 MAXMODULES 변경에 대해 설명한다.
다음은 기존의 MAXMODULES 변경하는 방법이다. 모듈의 재배치가 필요하기 때문에 많은 시간이 소요되는 단점이 있다.
> tdlrm > tdlinit
tdlsync와 tdlinit을 이용한 MAXMODULES 변경 방법은 다음과 같다.
변경된 MAXMODULES 값을 기반으로 새로운 인덱스만 계산하여 초기화한다. 모듈의 재배치 과정이 없기 때문에, “4.4.1. 기존의 MAXMODULES 변경”의 방식보다 시간과 비용이 절감된다.
> tdlsync -B original_maxmodules.bak - tdl.cfg 의 MAXMODULES 값을 변경 > tdlinit -B original_maxmodules.bak