Dynamic loading: Difference between revisions

Content deleted Content added
Adding local short description: "Mechanism by which a computer program can load a library (or other binary) into memory", overriding Wikidata description "mechanism by which a computer program can, at run time, load a library 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" (Shortdesc helper)
 
(26 intermediate revisions by 21 users not shown)
Line 3:
{{Redirect-distinguish2|Dynamically loaded library|[[dynamic-link library|dynamically linked library]]}}
{{Use dmy dates|date=July 2019|cs1-dates=y}}
'''Dynamic loading''' is a mechanism by which a [[computer program]] can, at [[Run time (program lifecycle phase)|run time]], load a [[Library (computing)|library]] (or other [[Executable file|binary]]) into memory, retrieve the addresses of functions and variables contained in the library, execute those [[library function|functions]] or access those variables, and unload the library from memory. It is one of the 3three mechanisms by which a computer program can use some other software; within the otherprogram; twothe areothers are [[static linking]] and [[dynamic linking]]. Unlike static linking and dynamic linking, dynamic loading allows a [[computer program]] to start up in the absence of these libraries, to discover available libraries, and to potentially gain additional functionality.<ref name="autobook"/><ref name="Elf_Dynamic_Loading"/>
 
==History==
Line 11:
* Libraries could be protected from unauthorized modification
 
[[IBM]]'s strategic [[transaction processing]] system, [[CICS]] (1970s onwards) uses dynamic loading extensively both for its [[Kernelkernel (computingoperating system)|kernel]] and for normal [[application program]] loading. Corrections to application programs could be made offline and new copies of changed programs loaded dynamically without needing to restart CICS<ref name="CICS"/><ref name="CEMT"/> (which can, and frequently does, run [[24/7]]).
 
[[Shared libraries]] were added to Unix in the 1980s, but initially without the ability to let a program load additional libraries after startup.<ref name="spe"/>
Line 19:
 
==In C/C++==
Not all systems support dynamic loading. [[UNIXUnix-like]] operating systems such as [[macOS]], [[Linux]], and [[Solaris (operating system)|Solaris]] provide dynamic loading with the [[C (programming language)|C programming language]] "dl" library. The [[Microsoft Windows|Windows]] [[operating system]] provides dynamic loading through the [[Windows API]].
 
===Summary===
Line 25:
|-
! Name
! [[UNIXUnix|Standard POSIX/UNIXUnix API]]
! [[Windows API|Microsoft Windows API]]
|-
Line 51:
 
===Loading the library===
Loading the library is accomplished with <code>LoadLibrary</code> or <code>LoadLibraryEx</code> on [[Microsoft Windows|Windows]] and with <code>dlopen</code> on [[UNIXUnix-like]] [[operating system]]s. Examples follow:
 
====Most UNIXUnix-like operating systems (Solaris, Linux, *BSD, etc.)====
<syntaxhighlight lang="c">
void* sdl_library = dlopen("libSDL.so", RTLD_LAZY);
if (!sdl_library == NULL) {
// report error ...
} else {
Line 64:
 
====macOS====
As a [[UNIXUnix]] library:
 
<syntaxhighlight lang="c">
void* sdl_library = dlopen("libSDL.dylib", RTLD_LAZY);
if (!sdl_library == NULL) {
// report error ...
} else {
Line 79:
<syntaxhighlight lang="c">
void* sdl_library = dlopen("/Library/Frameworks/SDL.framework/SDL", RTLD_LAZY);
if (!sdl_library == NULL) {
// report error ...
} else {
Line 104:
<syntaxhighlight lang="c">
HMODULE sdl_library = LoadLibrary(TEXT("SDL.dll"));
if (!sdl_library == NULL) {
// report error ...
} else {
Line 112:
 
===Extracting library contents===
Extracting the contents of a dynamically loaded library is achieved with <code>GetProcAddress</code> on [[Microsoft Windows|Windows]] and with <code>dlsym</code> on [[UNIXUnix]]-like [[operating system]]s.
 
====UNIXUnix-like operating systems (Solaris, Linux, *BSD, macOS, etc.)====
<syntaxhighlight lang="c">
void* initializer = dlsym(sdl_library, "SDL_Init");
if (!initializer == NULL) {
// report error ...
} else {
Line 138:
====Windows====
<syntaxhighlight lang="c">
FARPROC initializer = GetProcAddress(sdl_library, "SDL_Init");
if (!initializer == NULL) {
// report error ...
} else {
Line 150:
 
====Windows====
In the Windows case, the conversion is straightforward, since FARPROC is essentially already a [[function pointer]]:
 
<syntaxhighlight lang="c">
Line 163:
</syntaxhighlight>
 
====UNIXUnix (POSIX)====
According to the POSIX specification, the result of <code>dlsym()</code> is a <code>void</code> pointer. However, a function pointer is not required to even have the same size as a data object pointer, and therefore a valid conversion between type <code>void*</code> and a pointer to a function may not be easy to implement on all platforms.
 
Line 175:
<syntaxhighlight lang="c">
typedef void (*sdl_init_function_type)(void);
union { sdl_init_function_type func; void * obj; } alias;
alias.obj = initializer;
sdl_init_function_type init_func = alias.func;
Line 192:
 
===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 [[computer file|file]] which contains the library. Unloading the library is accomplished with <code>FreeLibrary</code> on [[Microsoft Windows|Windows]] and with <code>dlclose</code> on UNIXUnix-like [[operating system]]s. However, unloading a DLL can lead to program crashes if objects in the main application refer to memory allocated within the DLL. For example, if a DLL introduces a new class and the DLL is closed, further operations on instances of that class from the main application will likely cause a memory access violation. Likewise, if the DLL introduces a factory function for instantiating dynamically loaded classes, calling or dereferencing that function after the DLL is closed leads to undefined behaviour.
 
====UNIXUnix-like operating systems (Solaris, Linux, *BSD, macOS, etc.)====
<syntaxhighlight lang="c">
dlclose(sdl_library);
Line 205:
 
===Special library===
The implementations of dynamic loading on [[UNIXUnix-like]] operating systems and [[Microsoft Windows|Windows]] allow programmers to extract symbols from the currently executing process.
 
UNIXUnix-like operating systems allow programmers to access the global symbol table, which includes both the main executable and subsequently loaded dynamic libraries.
 
[[Microsoft Windows|Windows]] allows programmers to access symbols exported by the main executable. Windows does not use a global symbol table and has no API to search across multiple modules to find a symbol by name.
 
====UNIXUnix-like operating systems (Solaris, Linux, *BSD, macOS, etc.)====
<syntaxhighlight lang="c">
void* this_process = dlopen(NULL, 0);
</syntaxhighlight>
 
Line 221:
 
HMODULE this_process_again;
GetModuleHandleEx(0, 0, &this_process_again);
</syntaxhighlight>
 
==In Java==
{{further|Java Classloaderclass loader}}
In the [[Java programming language]], [[Java class|classes]] can be dynamically loaded using the '''{{Javadoc:SE|java/lang|ClassLoader}}''' object. For example:
 
Line 247:
 
==Platforms without dynamic loading==
Despite its promulgation in the 1980s through UNIXUnix and Windows, some systems still chose not to add—or even to remove—dynamic loading. For example, [[Plan 9 from Bell Labs]] and its successor 9front intentionally avoid dynamic linking, as they consider it to be "harmful".<ref name="Cat-V"/> The [[Go (programming language)|Go programming language]], by some of the same developers as Plan 9, also did not support dynamic linking, but plugin loading is available since [https://tip.golang.org/doc/go1.8 Go 1.8] (February 2017). The Go runtime and any library functions are statically linked into the compiled binary.<ref name="Golang"/>
 
==See also==
Line 263:
* [[FlexOS]]<!-- might at a later stage be incorporated in the article body as example of a system supporting dynamic loading/unloading of modular subdrivers -->
* [[GNU linker]]
* [[gold (linker)]]
* [[Lazy loading]]
* [[Library (computing)]]
* [[Linker (computing)]]
Line 271 ⟶ 273:
* [[Relocation (computer science)]]
* [[Relocation table]]
* [[Resident System Extension]] (RSX)<!-- dynamic (but not delayed) loading/unloading of modules under CP/M-related systems -->
* [[Static library]]
* [[Terminate-and-stay-resident program]] (TSR)<!-- dynamic (but not delayed) loading of system extensions under DOS-related systenms -->
* [[gold (linker)]]
* [[prelink]]
{{div col end}}
 
Line 282 ⟶ 284:
<ref name="CICS">{{Cite web |url=http://publib.boulder.ibm.com/infocenter/cicsts/v3r1/index.jsp?topic=/com.ibm.cics.ts31.doc/dfhp3/dfhp3oq.htm |title=Using the CICS-supplied procedures to install application programs}}</ref>
<ref name="CEMT">{{Cite web |url=http://www-01.ibm.com/support/docview.wss?uid=swg21031546 |title=IBM CEMT NEWCOPY or PHASEIN request fails with NOT FOR HOLD PROG - United States |date=2013-03-15}}</ref>
<ref name="spe">{{cite journal |title=An approach to genuine dynamic linking |author-first1=W. Wilson |author-last1=Ho |author-first2=Ronald A. |author-last2=Olsson |date=1991 |journal=Software—PracticeSoftware: Practice and Experience |volume=21 |issue=4 |pages=375–390 |doi=10.1002/spe.4380210404 |citeseerx=10.1.1.37.933|s2cid=9422227 }}</ref>
<ref name="apache">[{{Cite web |url=http://httpd.apache.org/docs/1.3/dso.html |title=Apache 1.3 Dynamic Shared Object (DSO) Support] |access-date=2007-12-31 |archive-date=2011-04-22 |archive-url=https://web.archive.org/web/20110422182003/http://httpd.apache.org/docs/1.3/dso.html |url-status=dead }}</ref>
<ref name="gcc-strict-aliasing">[https://gcc.gnu.org/onlinedocs/gcc-4.3.2/gcc/Optimize-Options.html#index-fstrict_002daliasing-721 GCC 4.3.2 Optimize Options: -fstrict-aliasing]</ref>
<ref name="POSIX_dlopen">[http://www.opengroup.org/onlinepubs/009695399/functions/dlsym.html POSIX documentation on <code>dlopen()</code>] (issues 6 and 7).</ref>
Line 300 ⟶ 302:
** [https://github.com/danfuzz/dl-example Dynamic Library Loading Example] (complete but concise working example)
** [https://developer.apple.com/library/mac/#DOCUMENTATION/DeveloperTools/Conceptual/DynamicLibraries/000-Introduction/Introduction.html#//apple_ref/doc/uid/TP40001908-SW1 Dynamic Library Programming Topics from Apple Developer Connection (targeted to macOS)]
* C/C++ UNIXUnix API:
** [http://www.opengroup.org/onlinepubs/009695399/functions/dlopen.html dlopen]
** [http://www.opengroup.org/onlinepubs/009695399/functions/dlsym.html dlsym]