Dynamic loading: Difference between revisions

Content deleted Content added
Undid revision 1045450571 by 174.47.95.32 (talk) - rv randomness
 
(20 intermediate revisions by 17 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 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 264:
* [[GNU linker]]
* [[gold (linker)]]
* [[Lazy loading]]
* [[Library (computing)]]
* [[Linker (computing)]]
Line 274 ⟶ 275:
* [[Resident System Extension]] (RSX)<!-- dynamic (but not delayed) loading/unloading of modules under CP/M-related systems -->
* [[Static library]]
* [[Terminate -and-stay-resident Stay Residentprogram]] (TSR)<!-- dynamic (but not delayed) loading of system extensions under DOS-related systenms -->
{{div col end}}
 
Line 283 ⟶ 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 301 ⟶ 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]