Table of Contents
TerraLib Common Runtime → Library
Every operational system provides some support for dealing with shared libraries. For instance, in Microsoft Windows a shared library is usually called a Dynamic Linking Library or DLL. In all Linux flavours it is called a Dynamic Shared Object or DSO or just SO. In Mac OS X it is named Dynamic Library or DyLib.
The TerraLib Library class provides a platform independent support for handling shared libraries. It can be used to load and unload shared libraries at runtime, to retrieve the name of a library and to give access to the functions and data in the library based in their addresses.
Design
The class Library is showned below:
The methods provided in this class allows:
- to load a shared library at construction time
- to delay the load of a library to be explicitly called by the method
load
- to explicitly unload the library through the
unload
method - to automatically unload the library from memory at destruction time
- to retrieve the shared library file name as informed in the constructor (
getFileName
method) - to search for a function within the library (
getAddress
method) - to form the library name independently of platform. Given a library name without file extensions, prefixes and nor suffixes the
getNativeName
method can be used to construct a library name according to the specifc platform - to add a new dir to the path used by the operational system to lookup for shared libraries (
addSearchDir
method) - to retrieve the system lookup path (
getSearchPath
method)
Besides the Library class we also provide a singleton called LibraryManager that can be used to observe the available libraries in the system. The picture above shows this class. Some attention is needed because this singleton doesn't control the libraries lifetime, it just make smart references to them that will be automatically removed when a library goes out of scope (or been destroyed) - no one is using them.
From Theory to Practice
The following code snnipet shows how to load a DLL called my.dll:
// TerraLib #include <terralib/common/Library.h> int main(int argc, char** argv) { te::common::Library l1("my.dll"); }
If you want to access a function defined in the shared library you can use the getAddress
method. The searched function must be declared with the extern “C”
modifier:
extern "C" void FunctionName() { ... }
This requirement is due to C++ compilers, they all performs what is called name-mangling. There is no standard across compilers on how name mangling is doing. So if your function is defined as extern “C”
, you can write something like:
// TerraLib #include <terralib/common/Library.h> int main(int argc, char** argv) { te::common::Library l1("my.dll"); void* f = l1.getAddress("FunctionName"); // now you can cast the pointer f to make a call ... }
Final Remarks
- We will need to create a concept of RefLibrary to allow the code from the own executable to be searched at runtime. This class will not unload the module at the end.
- We need another implementation for the library name that retrieves its name with full path
- We can keep a dependency list between libraries