Tuesday, 23 July 2019

Dynamic loading lib(run time load or patch update)

dlopen:

void * dlopen(const char *filename, int flag);
Flag:
  RTLD_LAZY --> ``resolve undefined symbols as code from the dynamic library is
                  executed''
  RTLD_NOW  --> ``resolve all undefined symbols before dlopen() returns and 
                  fail if this cannot be done''
                  opening the library take slightly longer (but it speeds up 
                  lookups later);  
  RTLD_GLOBAL --> Optional -> external symbols defined in the library will be made
                  available to subsequently loaded libraries

  • If the libraries depend on each other (e.g., X depends on Y), then you need to load the dependees first (in this example, load Y first, and then X).

Return:

  • ``handle'' that should be considered an opaque value to be used by the other DL library routines.
  • Return NULL On error.

dlerror:

  • which returns a string describing the error from the last call to dlopen(), dlsym(), or dlclose().
  • Return null if there is no error.
  • Call dlerror() first (to clear any error condition that may have existed), then call dlsym() to request a symbol, then call dlerror() again to see if an error occurred.

dlsym:

void * dlsym(void *handle, char *symbol);
      handle -> value returned from dlopen
      symbol -> NIL-terminated string.

Note:

For Run time patch(Dynamic loading the .so file):
   We must close the old handler & re open the library again,if there is
   any change in library. Otherwise changes won't be loaded.
   Hence for Run time patch, we must close & open the library again.

Return:

  • Return a NULL result if the symbol wasn't found.   

dlclose:

  • Closes a DL library.
  •  The dl library maintains link counts for dynamic file handles, so a dynamic library is not actually deallocated until dlclose has been called on it as many times as dlopen has succeeded on it.
  •  It's not a problem for the same program to load the same library multiple times.

Return:

  • Returns 0 on success, and non-zero on error

Program:

Program 1: create shared library:

 

/* Dynamic loading lib(run time load or patch update)
 * Check : http://velrajcoding.blogspot.in
 */

#include <stdio.h>

void run_load()
{
    printf("Velraj Run time loading 1st \n");


    return;
}
 

Program 2: Dynamic loader program:

 
/* Dynamic loading lib(run time load or patch update)
 * Check : http://velrajcoding.blogspot.in
 */

#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>

#define LIB_USR_DEF   "~/velrajk/sample/learn/librunlib.so"

enum {
    DL_LOAD_LIB = 1,
    DL_CALL_FUN,
    DL_EXIT,
};

void hline(char ch)
{
    int i = 0;

    for ( ; i < 80; printf("%c", ch), i++);
    printf("\n");

    return;
}
int main(int argc, char **argv)
{
    void *handle = NULL;
    void (*fun_symbol)();
    char *ret = NULL;
    int  ch = 0;

    while (1) {
        printf("\n\n");
        hline('*');
        printf("Find the DL library options:  \n\t 1. Load the library\n\t 2.Call the function\n\t 3.Exit\n Enter your choice:   ");
        scanf("%d", &ch);

        switch (ch) {
            case DL_LOAD_LIB:
                /*
                 * For Run time path:
                 *       We must close the old handler & re open the library again, if there is any change in library.
                 *       Otherwise changes won't be loaded.
                 *       Hence for Run time patch, we must close & open the library again.
                 */
                if (handle) {
                    dlclose(handle);
                }
                handle = dlopen(LIB_USR_DEF, RTLD_LAZY);
                if (!handle) {
                    fputs (dlerror(), stderr);
                    continue;
                }
                printf("Successfully opened an library \n");
                break;
            case DL_CALL_FUN:
                /* clear error code */
                dlerror();
                fun_symbol = dlsym(handle, "run_load");
                if ((ret = dlerror()) != NULL)  {
                    /* handle error, the symbol wasn't found */
                    printf("dlerror return error msg as:%s \n", ret);
                    continue;
                }

                /* symbol found, calling the symbol */
                (*fun_symbol)();
                break;
            case DL_EXIT:
                exit(1);
                break;
            default:
                printf("Choose the correct choice \n");
                break;
        }
    }

    dlclose(handle);

    return 0;
}
 

Output:

Program 1: Create Library

   :~/velrajk/sample/learn$ gcc -fPIC -shared -o librunlib.so dl_run_lib.c

Program 2: Dynamic loading

   :~/velrajk/sample/learn$ gcc dlopen.c -ldl


:~/velrajk/sample/learn$ ./a.out


********************************************************************************
Find the DL library options:
         1. Load the library
         2.Call the function
         3.Exit
 Enter your choice:   1
Successfully opened an library


********************************************************************************
Find the DL library options:
         1. Load the library
         2.Call the function
         3.Exit
 Enter your choice:   2
Velraj Run time loading 1st


********************************************************************************
Find the DL library options:
         1. Load the library
         2.Call the function
         3.Exit
 Enter your choice:



<!-- Here itself changed the library content as 2nd but without dlclose & dlopen, new value won't effect -->

2
Velraj Run time loading 1st


********************************************************************************
Find the DL library options:
         1. Load the library
         2.Call the function
         3.Exit
 Enter your choice:   2
Velraj Run time loading 1st


********************************************************************************
Find the DL library options:
         1. Load the library
         2.Call the function
         3.Exit
 Enter your choice:   2
Velraj Run time loading 1st


********************************************************************************
Find the DL library options:
         1. Load the library
         2.Call the function
         3.Exit
 Enter your choice:   1
Successfully opened an library


********************************************************************************
Find the DL library options:
         1. Load the library
         2.Call the function
         3.Exit
 Enter your choice:   2
Velraj Run time loading 2nd


********************************************************************************
Find the DL library options:
         1. Load the library
         2.Call the function
         3.Exit
 Enter your choice:   3

Reference:
    http://tldp.org/HOWTO/Program-Library-HOWTO/dl-libraries.html
    https://developer.ibm.com/tutorials/l-dynamic-libraries/
 

Shared library program:   Shared Libraries with GCC on linux


No comments:

Post a Comment