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.