| || |
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
dlopen ed. 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 <dlfcn.h> 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.