Chapter 4. Example

Table of Contents

4.1. Basic Usage Example
4.2. C++ Interface Usage Example
4.3. Explicit Version Protection Usage Example
4.4. Example of Additional Features
4.4.1. Existing MAXMODULES Change
4.4.2. MAXMODULES Change Using tdlsync and tdlinit

This chapter describes examples of API usage.

4.1. Basic Usage Example

  1. 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;
     }
    
    
  2. 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);
     }

4.2. C++ Interface Usage Example

This section describes an interface using TDL in C++.

  1. 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; }

  2. 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;
    }
  3. 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

4.3. Explicit Version Protection Usage Example

#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);
}

4.4. Example of Additional Features

This section describes the existing MAXMODULES change feature and the MAXMODULES change feature using tdlsync and tdlinit. They are included in TDL configuration.

4.4.1. Existing MAXMODULES Change

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

4.4.2. MAXMODULES Change Using tdlsync and 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