TOC   Previous   Next

Dynamically Loaded Libraries

The dlopen API allows a program to:

  1. open a shared library at run-time,

  2. search for a function (or variable) by name in that library,

  3. and then call the function (or access the variable).

Shared libraries loaded at run-time are referred to as dynamically loaded libraries


dlopen API:

Four key functions: dlopen(), dlerror(), dlsym(), and dlclose().


void *dlopen(const char *filename, int flag);

dlopen() opens library, and increments the library's count of open references.


const char *dlerror(void);

dlerror() returns a pointer to a message string after an error return from dlopen(), dlsym(), or dlclose().

Returns NULL if no error has occurred since last call to dlerror().


void *dlsym(void *handle, char *symbol);

dlsym() searches a library to find a symbol (e.g., a function) and return its address.


int dlclose(void *handle);

dlclose() decrements the count of open references to the library.

If reference count falls to zero, library is unloaded.


Example - dynload.c:

/* Usage: dynload lib-path func-name */

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

int
main(int argc, char *argv[])
{
    void *libHandle;            /* Handle for shared library */
    void (*funcp)(void);        /* Pointer to function with no args */
    char *err;

    if (argc != 3) {            /* Check command line arguments */
        fprintf(stderr, "Usage: %s lib-path func-name\n", argv[0]);
        exit(EXIT_FAILURE);
    } /* if */

    /* Load the shared library and get a handle for later use */

    libHandle = dlopen(argv[1], RTLD_NOW);
    if (libHandle == NULL) {
        fprintf(stderr, "Error on dlopen: %s\n", dlerror());
        exit(EXIT_FAILURE);
    } /* if */

    /* Get a pointer to named function inside library */

    (void) dlerror();           /* Clear dlerror() */
	
    /* The strange cast below is required by C99, which	forbids 
        assignment between a function pointer and void * */
	
    *(void **) (&funcp) = dlsym(libHandle, argv[2]);
    
    err = dlerror();
    if (err != NULL) {  /* Non-NULL from dlerror() means we got error */
        fprintf(stderr, "Error on dlsym: %s\n", err);
        exit(EXIT_FAILURE);
    } /* if */

    /* If the function address is non-NULL try calling it */

    if (funcp == NULL)
        printf("%s is NULL\n", argv[2]);
    else
        (*funcp)();

    /* And close the library */

    dlclose(libHandle);

    exit(EXIT_SUCCESS);
} /* main */

$ LD_LIBRARY_PATH=. ./dynload libdemo.so.1 x1
Called mod1-x1

(C) 2006, Michael Kerrisk