Dynamic loading
Dynamic loading is a mechanism by which a computer program can, at runtime, load a library (or other binary) into memory, retrieve the addresses of functions and variables contained in the library, execute those functions or access those variables, and unload the library from memory. Unlike static linking and delayed loading, this mechanism allows a computer program to startup in the absence of these libraries, to discover available libraries, and to potentially gain additional functionality. [1][2]
Uses
Dynamic loading is most frequently used in implementing computer plugins [1]. For example, the Apache Web Server's *.dso
"dynamic shared object" plugin files are libraries which are loaded at runtime with dynamic loading [3]. Dynamic loading is also used in implementing computer programs where multiple different libraries may supply the requisite functionality and where the user has the option to select which library or libraries to provide.
In C/C++
Not all systems support dynamic loading. UNIX-like operating systems such as Mac OS X, Linux, and Solaris provide dynamic loading with the C programming language "dl" library. The Windows operating system provides dynamic loading through the Windows API.
Summary
Name | Windows API | POSIX/UNIX API |
---|---|---|
Header file inclusion | #include <windows.h>
|
#include <dlfcn.h>
|
Definitions for header | Kernel32.dll
|
dl (libdl.so , libdl.dylib , etc. depending on the OS)
|
Loading the library | LoadLibrary LoadLibraryEx |
dlopen
|
Extracting contents | GetProcAddress
|
dlsym
|
Unloading the library | FreeLibrary
|
dlclose
|
Loading the Library
Loading the library is accomplished with LoadLibrary
or LoadLibraryEx
on Windows and with dlopen
on UNIX-like operating systems. Examples follow:
Linux
void* sdl_library = dlopen("libsdl.so", RTLD_LAZY); if ( sdl_library == NULL ){ // report error ... }else{ // use the result in a call to dlsym }
Mac OS X
As an UNIX library:
void* sdl_library = dlopen("libsdl.dylib", RTLD_LAZY); if ( sdl_library == NULL ){ // report error ... }else{ // use the result in a call to dlsym }
As an OS X Framework:
void* sdl_library = dlopen("/Library/Frameworks/SDL.framework/SDL", RTLD_LAZY); if ( sdl_library == NULL ){ // report error ... }else{ // use the result in a call to dlsym }
Windows
HMODULE sdl_library = LoadLibrary("SDL.dll"); if ( sdl_library == NULL ){ // report error ... }else{ // use the result in a call to GetProcAddress }
Extracting Library Contents
Extracting the contents of a dynamically loaded library is achieved with GetProcAddress
on Windows and with dlsym
on UNIX-like operating systems.
Windows
void* initializer = GetProcAddress(sdl_library,"SDL_Init"); if ( initializer == NULL ){ // report error ... }else{ // cast initializer to its proper type and use }
Mac OS X, Linux, Solaris, and UNIX/BSD-like Operating Systems
void* initializer = dlsym(sdl_library,"SDL_Init"); if ( initializer == NULL ){ // report error ... }else{ // cast initializer to its proper type and use }
Converting Extracted Library Contents
The C++ programming language prohibits conversion between type void*
and a pointer to a function. The following code snippet demonstrates a workaround which allows for this conversion:
typedef int (*sdl_init_function_type)(Uint32); sdl_init_function_type init_func = *((sdl_init_function_type*)(&initializer));
Unloading the Library
Loading a library causes memory to be allocated; the library must be deallocated in order to avoid a memory leak. Additionally, failure to unload a library can prevent filesystem operations on the file which contains the library. Unloading the library is accomplished with FreeLibrary
on Windows and with dlclose
on UNIX-like operating systems.
Windows
FreeLibrary(sdl_library);
Mac OS X, Linux, Solaris, and UNIX/BSD-like Operating Systems
dlclose(sdl_library);
Special Library
Both Windows and UNIX implementations of dynamic loading allow programmers to extract symbols from the currently executing process. In both of these APIs, the currently executing process can be "loaded" such that the result can be used in the same manner as the result from dynamically loading a library with LoadLibrary
or dlopen
.
Windows
HMODULE this_process; GetModuleHandleEx(0,0,&this_process);
Mac OS X, Linux, Solaris, and UNIX/BSD-like Operating Systems
void* this_process = dlopen(0,0);
In Java
In the Java programming language, classes can be dynamically loaded using the ClassLoader
object. For example:
Class type = ClassLoader.getSystemClassLoader().loadClass(name); Object obj = type.newInstance();
See also
External links
- General Links
- C/C++ UNIX API:
- C/C++ Windows API:
- Java API: