Table of Contents
This chapter describes examples of API usage.
Compile the following functions using a dynamic module to create my_function.sl.
#include <tdlcall.h> /* Function to be called by tdlcall */ long my_function(void *args) { long urcode; urcode = (long)time (NULL); strcpy((char*)args, "my_function"); return urcode; }
The part that uses this module uses as follows:
/* To use the TDL-related functions, 'include' must be needed. */ #include <tdlcall.h> int retval; char data[256]; long urcode; /* Call the tdlcall function: 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 { /* Outputs values received from my_function */ printf("tdlcall(%s) = %d, urcode = %#08x, data = %s\n","my_function", retval, urcode, data); }
This section describes an interface using TDL in C++.
Compile the following functions using a dynamic module to create 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; }
The part that uses this module uses as follows:
#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; }
Since it is difficult for the class to accurately identify symbols in nm, tdlinit and tdlupdate need exp files. How to use export files is as follows:
If VERSION is set to 1, 2, or 3, the function names are listed one per each line. If VERSION is set to 4, the class names are listed one per each line. If name spaces are applied, list one per each line in the form of "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"); /* Start explicit version protection by calling 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); } /* End explicit version protection by calling tdlend */ tdlend(); strcat((char *)msg->data, rcvbuf); msg->len = strlen((char *)msg->data); tpreturn(TPSUCCESS,0,(char *)msg->data, msg->len, 0); }
This section describes the existing MAXMODULES change feature and the MAXMODULES change feature using tdlsync and tdlinit. They are included in TDL configuration.
The following is the existing MAXMODULES change method. This method requires the relocation of the modules. Thus, it takes a long time, which is the disadvantage.
> tdlrm > tdlinit
The following is the MAXMODULES change method using tdlsync and tdlinit.
Initializes by calculating only the new index based on the changed MAXMODULES value. As this method does not require the relocation of the modules, time and cost is reduced than the method in "4.4.1. Existing MAXMODULES Change".
> tdlsync -B original_maxmodules.bak - Change the MAXMODULES value of tdl.cfg. > tdlinit -B original_maxmodules.bak