The dlopen API allows a program to:
Shared libraries loaded at run-time are referred to as dynamically loaded libraries
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.
Regardless of whether they will ever be required.
Load of library is slower, but any potential undefined symbol errors are detected immediately instead of later.
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