Loading/Unloading Shared Libraries
Introduction
All Derelict packages are bindings to C shared libraries. No package in Derelict
is designed to work with static C libraries. The interface for loading and
unloading shared libraries is the same for all packages in Derelict, so the
instructions on this page apply to each package. However, some libraries may have
special features that require more than the common loader interface. Any such
exceptions will be noted in the documentation for those packages.
Derelict's Common Loader Interface
You are probably already aware of Derelict's package naming convention. Each
package name is a combination of 'Derelict' with some form of the name of the
library the package binds with. No matter what form of the library name is used,
the Derelict package name is the same throughout all documentation and code
related to that package. For example, DerelictGL is always referred to as
'DerelictGL'. If you aren't sure about a package name, look at the documentation
list at the bottom of the
front page. All of the package document titles in
that list correlate to Derelict package names.
Loading and unloading shared libraries is done through a global object declared
in each Derelict package. The object is named exactly as the package in which it
is declared. The loader interface defines load methods that can be used to load
a shared library into memory, and an unload method that can be used to remove
the shared library from memory.
Loading
The important thing to remember about loading is that
a package's load method must be called before any functions
from the bound library can be used. If you tried to use a library function
without first calling the load method for that package, you would find yourself
with an access violation. The library interface consists of function pointers.
The load method pulls the shared library in to memory and points each function
pointer to the address of the appropriate function. Until that time, the function
pointers are all null.
As an example, if you were using DerelictSDL, you would use the following
syntax to load the SDL shared library:
DerelictSDL.load();
From that point onward you would be able to use all SDL functions normally.
The load method accepts an optional shared library name string parameter that will
overload the default search mechanism. For example, on Windows DerelictAL attempts
to load "openal32.dll" by default. Some systems have audio drivers that provide
a hardware accelerated version of OpenAL, some do not. You may want to ship the
OpenAL dll with your app, but renamed to something like "myopenal.dll", or perhaps
with the same name but in a subdirectory of the application directory ("al/openal32.dll").
If the DerelictAL.load() fails, then you can call
DerelictAL.load("myopenal.dll") instead. This is important because
Windows (and other OSes) will look in the application's directory for a given
shared library before looking in system directories. If you were to drop openal32.dll
in your application's directory, that version would be loaded every time and any
hardware accelerated version in the system directories would be ignored. This
technique can be used for every Derelict package, not just DerelictAL.
Sometimes, loads fail. There are several root causes for this, the end result
being either that the system couldn't find the shared library or that one of the
functions Derelict expected to find in the library wasn't there. In either
case, the load method will throw an exception. You can read more about Derelict
exceptions in the documentation for DerelictUtil.
You can also learn how to bypass some exceptions in the documentation on
Derelict's selective loading system.
Unloading
Unloading a shared library uses the same syntax as when loading, but you call
the unload method instead:
DerelictSDL.unload();
In normal usage of Derelict, you do not need to unload
any of the shared libraries. Derelict will do this for you automatically.
The unload method is provided as a convenience for those who want to implement
hot swapping or want to free up memory if a library is no longer needed during
execution.
Loader Properties
Loaders have two properties you may find useful. The loaded property
is true if the loader's shared library has been loaded, false if not. The libName
property will return the name of the shared library that has been loaded, or null
when the loader has no library loaded.
Note For Linux/Mac Users
On Linux and Mac, there is one additional dependency that must be linked into
your executable: libdl. On Windows, the functions used to load shared libraries
are part of the core libraries linked automatically during compilation. On other
platforms, this is not the case. So any time you compile a Derelict application
on Linux or Mac, regardless of whether you are using DMD or GDC, you must link
to libdl. Otherwise, compilation will fail with symbol errors.