[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Probably the best known and supported Unix run time linking API is the ‘dlopen’ interface, used by Solaris and GNU/Linux amongst others, and discussed earlier in Dynamic Loading. libltdl is based on the ‘dlopen’ API, with a few small differences and several enhancements.
The following libltdl API functions are declared in ‘ltdl.h’:
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, libltdl will search for it in directories named in the ‘LTDL_LIBRARY_PATH’ environment variable, and then in the standard library directories before giving up. It is safe to call this function many times, libltdl will keep track of the number of calls made, but will require the same number of calls to ‘lt_dlclose’ to actually unload the module.
Returns the address of the named symbol in the module which returned
handle when it was lt_dlopen
ed. You must cast the returned
address to a known type before using it.
When you are finished with a particular module, it can be removed from memory using this function.
If any of the libltdl API calls fail, this function returns a string which describes the last error that occurred.
In order to use these functions, you must #include <ltdl.h>
for
the function prototypes, and link with ‘-lltdl’ to provide the
API implementation. Assuming you link your application with
libtool
, and that you call the necessary macros from your
‘configure.in’ (see section Using libltdl), then any host specific
dependent libraries (for example, ‘libdl’ on GNU/Linux) will
automatically be added to the final link line by libtool
.
You don’t limit yourself to using only Libtool compiled modules when you use libltdl. By writing the module loader carefully, it will be able to load native modules too—although you will not be able to preload non-Libtool modules (see section dlpreopen Loading. The loader in Module Loader is written in this way. It is useful to be able to load modules flexibly like this, because you don’t tie your users into using Libtool for any modules they write.
Compare the descriptions of the functions above with the API described in Module Access Functions. You will notice that they are very similar.
Back-linking is the process of resolving any remaining symbols by referencing back into the application that loads the library at runtime – a mechanism implemented on almost all modern Unices.
For instance, your main application may provide some utility function, ‘my_function’, which you want a module to have access to. There are two ways to do that:
- You could use Libtool to link your application, using the ‘-export-dynamic’ option to ensure that the global application symbols are available to modules. When libltdl loads a module into an application compiled like this, it will back-link symbols from the application to resolve any otherwise undefined symbols in a module. When the module is ‘ltdlopen’ed, libltdl will arrange for calls to ‘my_function’ in the module, to execute the ‘my_function’ implementation in the application.
If you have need of this functionality, relying on back-linking is the simplest way to achieve it. Unfortunately, this simplicity is at the expense of portability: some platforms have no support for back-linking at all, and others will not allow a module to be created with unresolved symbols. Never-the-less, libltdl allows you to do this if you want to.
- You could split the code that implements the symbols you need to share with modules into a separate library. This library would then be used to resolve the symbols you wish to share, by linking it into modules and application alike. The definition of ‘my_function’ would be compiled separately into a library, ‘libmy_function.la’. References to ‘my_function’ from the application would be resolved by linking it with ‘libmy_function.la’, and the library would be installed so that modules which need to call ‘my_function’ would be able to resolve the symbol by linking with ‘-lmy_function’.
This method requires support for neither back-linking nor unresolved link time symbols from the host platform. The disadvantage is that when you realise you need this functionality, it may be quite complicated to extract the shared functionality from the application to be compiled in a stand alone library.
On those platforms which support back-linking, libltdl can be configured to resolve external symbol references in a dynamic module with any global symbols already present in the main application. This has two implications for the libltdl API:
lt_dlopen
as might be necessary with the native module loading
API.
Similarly, there is no need to specify whether the module should be
integrated into the application core before lt_dlopen
returns, or
else when the symbols it provides are first referenced. libltdl
will use lazy loading if it is supported, since this is a slight
performance enhancement, or else fall back to loading everything
immediately. Between this feature and the support of back-linking,
there is no need to pass flags into lt_dlopen
as there is with
most native dlopen
APIs.
There are a couple of other important API functions which you will need when using libltdl:
You must call this function to initialise libltdl before calling any of the other libltdl API functions. It is safe to call this function many times, libltdl will keep track of the number of calls made, but will require the same number of calls to ‘lt_dlexit’ to actually recycle the library resources. If you don’t call ‘lt_dlinit’ before any other API call, the other calls, including ‘lt_dlerror’, will return their respective failure codes (‘NULL’ or ‘1’, as appropriate).
When you are done with libltdl and all dynamic modules have been unloaded you can call this function to finalise the library, and recycle its resources. If you forget to unload any modules, the call to ‘lt_dlexit’ will ‘lt_dlclose’ them for you.
Another useful departure that the libltdl API makes from a
vanilla dlopen
implementation is that it also will work correctly
with old K&R C compilers, by virtue of not relying on ‘void *’
pointers. libltdl uses lt_dlhandle
s to pass references to
loaded modules, and this also improves ANSI C compiler’s type
checking compared to the untyped addresses typically used by native
dlopen
APIs.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] |
This document was generated by Ben Elliston on July 10, 2015 using texi2html 1.82.