dlopen loads a dynamic library from the file named by the null terminated string filename and returns
an opaque "handle" for the dynamic library. If filename is not an absolute path (i.e., it does not
begin with a "/"), then the file is searched for in the following locations:
A colon-separated list of directories in the user’s LD_LIBRARY_PATH environment variable. The list of
libraries cached in /etc/ld.so.cache.
/lib, followed by /usr/lib.
If filename is a NULL pointer, then the returned handle is for the main program.
External references in the library are resolved using the libraries in that library’s dependency
list and any other libraries previously opened with the RTLD_GLOBAL flag. If the executable was linked
with the flag "-rdynamic", then the global symbols in the executable will also be used to resolve
references in a dynamically loaded library.
Flag must be either RTLD_LAZY, meaning resolve undefined symbols as code from the dynamic library is
executed, or RTLD_NOW, meaning resolve all undefined symbols before dlopen returns, and fail if this
cannot be done. Optionally, RTLD_GLOBAL may be or’ed with flag, in which case the external symbols
defined in the library will be made available to subsequently loaded libraries.
If the library exports a routine named _init, then that code is executed before dlopen returns.
If the same library is loaded twice with dlopen(), the same file handle is returned. The dl library
maintains link counts for dynamic file handles, so a dynamic library is not deallocated until dlclose
has been called on it as many times as dlopen has succeeded on it.
If dlopen fails for any reason, it returns NULL. A human readable string describing the most recent
error that occurred from any of the dl routines (dlopen, dlsym or dlclose) can be extracted with dlerror().
dlerror returns NULL if no errors have occurred since initialization or since it was last called.
(Calling dlerror() twice consecutively, will always result in the second call returning NULL.)
dlsym takes a "handle" of a dynamic library returned by dlopen and the null terminated symbol name,
returning the address where that symbol is loaded. If the symbol is not found, dlsym returns NULL;
however, the correct way to test for an error from dlsym is to save the result of dlerror into a variable,
and then check if saved value is not NULL. This is because the value of the symbol could actually
be NULL. It is also necessary to save the results of dlerror into a variable because if dlerror is
called again, it will return NULL.
There are two special pseudo-handles, RTLD_DEFAULT and RTLD_NEXT. The former will find the first
occurrence of the desired symbol using the default library search order. The latter, which is usable
only from within a dynamic library, will find the next occurrence of a function in the search order
after the current library. This allows one to provide a wrapper around a function in another shared library.
dlclose decrements the reference count on the dynamic library handle handle. If the reference count
drops to zero and no other loaded libraries use symbols in it, then the dynamic library is unloaded.
If the dynamic library exports a routine named _fini, then that routine is called just before the library
is unloaded.
RETURN VALUE
dlclose returns 0 on success, and non-zero on error.
EXAMPLE
Load the math library, and print the cosine of 2.0:
#include <stdio.h>
#include <dlfcn.h>
int main(int argc, char **argv) {
void *handle;
double (*cosine)(double);
char *error;
handle = dlopen ("libm.so", RTLD_LAZY);
if (!handle) {
fprintf (stderr, "%s/n", dlerror());
exit(1);
}
cosine = dlsym(handle, "cos");
if ((error = dlerror()) != NULL) {
fprintf (stderr, "%s/n", error);
exit(1);
}
printf("%f/n", (*cosine)(2.0));
dlclose(handle);
return 0;
}
If this program were in a file named "foo.c", you would build the pro-
gram with the following command:
gcc -rdynamic -o foo foo.c -ldl
NOTES
The symbols RTLD_DEFAULT and RTLD_NEXT are defined by <dlfcn.h> only
when _GNU_SOURCE was defined before including it.