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:

library classes

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

QR Code
QR Code wiki:designimplementation:common:library (generated for current page)