Dynamic loading
Dynamické načtení je mechanismus při běhu programu, kdy se načte knihovna do paměti, obdrží se adresy funkcí nebo proměnných, které se následně vykonají. Paměť se poté uvolní. Mechanismus dovoluje spuštění programu při absenci těchto knihoven, prozkoumání jiných dostupných knihoven a potencionálně získat další funkce.
Historie
Dynamické načtení bylo běžným mechanismem pro Operační systémy IBM/360 a to zejména pro I/O podrutiny, COBOL a PL/1 runtime knihovny. Doba načítání je transparentní, neboť je většinou řízena samotným operačním systémem (nebo jeho subsystémem). Mezi hlavní výhody patří:
- Opravy podsystému jsou uskutečneny v celém programu najednou, bez nutnosti znovunačtení
- Knihovny mohou být chráněny před nežádanou úpravou
Transakční zpracování IBM, CICS, používá dynamické načítání rozsáhle pro své jádro operačního systému, stejně tak pro normální aplikační program. Opravy těchto programů mouhou být uskutečněny offline a nové kopie nebo změny v programu načteny dynamicky bez nutnosti restartovat CICS.
Použití
Dynamické načítání je nejčastěji používáno v implementaci softwarových pluginů (Apache Web Server). Dalším příkladem může být implementace v programech, které nabízejí více podporovaných knihoven a uživatel si může libovolně zvolit.
C/C++
Dynamické načítání nepodporují všechny systémy. Mac OS X, Linux a Solaris nabízí dynamické načítání prostřednictvím programovacího jazyka C - “dl” knihovna. Operační systém widows skrze Windows API.
Shrnutí
Název | Standard POSIX/UNIX API | Microsoft Windows API |
---|---|---|
Zařazení hlavičkového souboru | #include <dlfcn.h>
|
#include <windows.h>
|
Definice hlavičky | dl
( |
Kernel32.dll
|
Načtení knihovny | dlopen
|
LoadLibrary LoadLibraryEx |
Extrahování obsahu | dlsym
|
GetProcAddress
|
Zavření knihovny | dlclose
|
FreeLibrary
|
Načtení knihovny
Načtení knihovny se provede prostřednictvím LoadLibrary
nebo LoadLibraryEx
na operačním systému Windows a pomocí dlopen
na operačních systémech na bázi Linuxu. Následují příklady:
(Linux, *BSD, Solaris, etc.)
void* sdl_library = dlopen("libSDL.so", RTLD_LAZY);
if(sdl_library == NULL) {
// oznámení chyby ...
} else {
// výsledek zavoláním dlsym
}
Mac OS X
UNIX library:
void* sdl_library = dlopen("libsdl.dylib", RTLD_LAZY);
if(sdl_library == NULL) {
// oznámení chyby ...
} else {
// výsledek zavoláním dlsym
}
void* sdl_library = dlopen("/Library/Frameworks/SDL.framework/SDL", RTLD_LAZY);
if(sdl_library == NULL) {
// oznámení chyby ...
} else {
// výsledek zavoláním dlsym
}
Windows
HMODULE sdl_library = LoadLibrary("SDL.dll");
if( sdl_library == NULL) {
//oznámení chyby ...
} else {
// výsledek zavoláním GetProcAddress
}
Extrahování obsahu knihovny
(Linux, *BSD, Mac OS X, Solaris, etc.)
void* initializer = dlsym(sdl_library,"SDL_Init");
if(initializer == NULL) {
// oznámení chyby ...
} else {
...
}
Windows
FARPROC initializer = GetProcAddress(sdl_library,"SDL_Init");
if(initializer == NULL) {
// report error ...
} else {
...
}
Převod extrahovaného obsahu knihovny
Vrácený výsledek prostřednictvím dlsym()
nebo GetProcAddress()
musí být převeden do požadované destinace předtím, než může být použit.
Windows
typedef INT_PTR (*FARPROC)(void);
Související články
Literatura
- General Links
- C/C++ UNIX API:
- C/C++ Windows API:
- Java API: