17.2 Module Access Functions
In order to access the functionality of dynamic modules, different
architectures provide various APIs to bring the code from the
module into the address space of the loading program, and to access the
symbols exported by that module.
GNU/Linux uses the dynamic module API introduced by Sun's
Solaris operating system, and widely adopted (and adapted!) by the
majority of modern Unices(39). The interface consists of four functions. In practice, you
really ought not to use these functions, since you would be locking your
project into this single API, and the class of machines that
supports it. This description is over-simplified to serve as a
comparison with the fully portable libltdl API described in
18. Using GNU libltdl. The minutiae are not discussed, because therein
lie the implementation peculiarities that spoil the portability of this
API. As they stand, these descriptions give a good overview of
how the functions work at a high level, and are broadly applicable to
the various implementations in use. If you are curious, the details of
your machines particular dynamic loading API will be available in
its system manual pages.
- Function: void * dlopen (const char *filename, int flag)
- This function brings the code from a named module into the address space
of the running program that calls it, and returns a handle which is used
by the other API functions. If filename is not an absolute
path, GNU/Linux will search for it in directories named in the
`LD_LIBRARY_PATH' environment variable, and then in the standard
library directories before giving up.
The flag argument is made by `OR'ing together various flag bits
defined in the system headers. On GNU/Linux, these flags are
defined in `dlfcn.h':
- Resolve undefined symbols when they are first used.
- If all symbols cannot be resolved when the module is loaded,
dlopen will fail and return `NULL'.
- All of the global symbols in the loaded module will be available to
resolve undefined symbols in subsequently loaded modules.
- Function: void * dlsym (void *handle, char *name)
- Returns the address of the named symbol in the module which returned
handle when it was
dlopened. You must cast the returned
address to a known type before using it.
- Function: int dlclose (void *handle)
- When you are finished with a particular module, it can be removed from
memory using this function.
- Function: const char * dlerror (void)
- If any of the other three API calls fails, this function returns a
string which describes the last error that occured.
In order to use these functions on GNU/Linux, you must
#include for the function prototypes, and link with
`-ldl' to provide the API implementation. Other Unices use
`-ldld' or provide the implementation of the API inside the
standard C library.