====== DLLs / dynamische Libraries / DSOs / shared libraries ======
**DLL**: Dynamic Link Library (Windows)\\ **DSO**: Dynamic Shared Object (ELF, Posix)
* Unix/Linux: dlopen(), dlsym(), dlclose(), dlerror(): [[http://linux.die.net/man/3/dlopen]]
* Mit Beispielen: [[http://tldp.org/HOWTO/C++-dlopen/thesolution.html]]
* Entwicklung von DLLs in Windows: [[http://msdn.microsoft.com/en-us/library/9yd93633.aspx|Linking an Executable to a DLL]]
* Building Windows **DLL**s with MinGW: [[http://www.transmissionzero.co.uk/computing/building-dlls-with-mingw/]] - Ein sehr guter Artikel!
* Shared libraries with GCC on Linux: [[https://www.cprogramming.com/tutorial/shared-libraries-linux-gcc.html]]
* Workaround beim [[edv:prg:mq-series:example:Kompilieren/Linken von mqic.dll/.lib mit GCC unter Windows]]
* [[EDV:PRG:CPP:Example:Export von Klassen/Strukturen/Methoden/Funktionen, die STL-Objekte (oder Templates allgemein) als Member/Parameter verwenden]] (Windowslastig)
* [[EDV:PRG:CPP:Example:Initialisierung und Deinitialisierung von dynamischen Libraries]] (Initialization and finalization functions / Library constructor and destructor functions / DllMain)
* [[EDV:PRG:CPP:Example:Export von Funktionen in den Libraries]] (GCC, Posix + Plattformübergreifend)
* Konflikte wegen den gleichen Namen:
* Shared Library Symbol Conflicts (on Linux): [[https://holtstrom.com/michael/blog/post/437/Shared-Library-Symbol-Conflicts-%28on-Linux%29.html]]
* Shared Library Symbol Conflicts (on Solaris): [[https://holtstrom.com/michael/blog/post/446/Shared-Library-Symbol-Conflicts-%28on-Solaris%29.html]]
* Solaris Export Symbols: [[https://holtstrom.com/michael/blog/post/455/Solaris-Export-Symbols.html]]
* [[EDV:PRG:C:Tipp:Namenskonflikte lösen, die durch die Verwendung externer Libraries mit gleichbenannten Funktionen entstehen]] (Windows-Beispiel)
* Auf **[[EDV:OS:UNIX:Derivate:AIX]]** in Kombination mit GCC unbedingt folgende Hinweise beachten:
* Using the GNU C/C++ compiler on AIX: [[http://www.ibm.com/developerworks/aix/library/au-gnu.html]]
* Auf AIX haben üblicherweise beide Libraries-Typen die Endung "**.a**" - sowohl die **statischen** als auch die **dynamischen**.
* AIX-spezifisches **ld**: [[https://www.ibm.com/support/knowledgecenter/ssw_aix_61/com.ibm.aix.cmds3/ld.htm]]
* AIX® Linking and Loading Mechanisms: [[http://download.boulder.ibm.com/ibmdl/pub/software/dw/aix/es-aix_ll.pdf]]
:!: Wenn aus der DLL/SO Symbole/Funktionen referenziert werden, die in der Executable definiert sind (also, Referenzierung in "umgekehrter" Richtung), dann hilft die Option "**-rdynamic**" beim Linken (GCC) weiter. Wie und warum, erklärt sehr anschaulich folgender Beitrag:\\ [[http://stackoverflow.com/questions/36692315/what-exactly-does-rdynamic-do-and-when-exactly-is-it-needed]]
===== Abhängigkeiten =====
Die Abhängigkeiten eines ausführbares Programms oder einer dynamischen Libraries werden mit **ldd** angezeigt:
juergen@developing:~> ldd /usr/lib/libglib-2.0.so
/usr/lib/libglib-2.0.so needs:
/usr/lib/libc.a(shr.o)
/usr/lib/libpthread.a(shr_xpg5.o)
/opt/freeware/lib/libintl.a(libintl.so.1)
/opt/freeware/lib/libiconv.a(libiconv.so.2)
/unix
/usr/lib/libcrypt.a(shr.o)
/usr/lib/libpthreads.a(shr_comm.o)
/opt/freeware/lib/libiconv.a(shr4.o)
juergen@developing:~>
Per Voreinstellung sucht der Loader nur in **/lib** und **/usr/lib**. Die Umgebungsvariable **LD_LIBRARY_PATH** ergänzt diese Suche um weitere (durch Doppelpunkte getrennte) Verzeichnisse.
===== Inhalt / enthaltene Funktionen / Symbols =====
Den Inhalt (die Symbols) einer Libraries mit dem Befehl **nm** anzeigen lassen:
juergen@developing:~> nm -g /usr/lib/libglib-2.0.so | head -10
.$PTRGL T 268536464
._Errno T 268482448
.__divi64 T 268633312
.__divss U 12800
.__divu64 T 268532584
.__divus U 12928
.__f64toi64rz T 268805056
.__f64tou64rz T 268643292
.__itrunc T 268643008 202
.__mulh U 12544
nm: /usr/lib/libglib-2.0.so: 0654-207 The sort process was stopped prematurely.
juergen@developing:~>
Falls sich **nm** mit folgender Fehlermeldung beschwert:
0654-210 xxxxx.o is not valid in the current object file mode.
Use the -X option to specify the desired object mode.
...dann nach dem "-g" mit dem zusätzlichen Parameter **-X64** versuchen (für AIX relevant).
:!: Mit der Option "**-g**" werden nur die **externen** Symbole angezeigt.
:!: Mit der Option "**-D**" werden anstelle "normaler" Symbole die **dynamischen** Symbole angezeigt.
Auch der Befehl **dump** ist in diesem Zusammenhang sehr nützlich.
===== Debugging von DLLs/DSOs =====
:!: Beim Laden eines DSOs wird der Initialisierungscode innerhalb des DSOs aufgerufen, bevor die **dlopen()** zurückkehrt. Diese Initialisierung ist UserCode und kann Fehler erzeugen, die nicht von dlopen() gefangen werden können. Beispielsweise wird ein mit **RTLD_LAZY** geladenes Objekt, das versucht, eine Funktion aufzurufen, die nicht lokalisiert werden kann, zu einer Prozessbeendigung führen. Fehlerhafte Programmierpraktiken innerhalb des Initialisierungscodes können auch zur Prozessbeendigung führen. Die "runtime linkers debugging"-Funktion kann helfen, diese Art von Fehler zu identifizieren. Eine davon ist die Environment-Variable **%%LD_DEBUG%%**.
==== LD_DEBUG (Environment-Variable) ====
Die Environment-Variable **%%LD_DEBUG%%** (bzw. LD_DEBUG_32 und LD_DEBUG_64), die als Argument eine durch Komma oder Doppelpunkt getrennte Liste von Tokens hat, veranlasst den RunTime-Linker, Debugging-Informationen auf **%%stderr%%** auszugeben.
Die Environment-Variable **%%LD_DEBUG_OUTPUT%%** kann ebenfalls definiert werden, um eine Datei anzugeben, an die die Debugging-Informationen gesendet werden sollen.
Hier ist ein Beispiel:
LD_DEBUG=files,bindings,detail
LD_DEBUG_OUTPUT=lari.dbg
Die Debug-Ausgabe wird ins File **lari.dbg.//PID//** geschrieben (PID ist die Prozess-ID).
:!: Die Tokens **files,bindings** sind i.d.R. völlig ausreichend. Das Token **detail** bläht das Ausgabe-File sehr stark auf (die Adressinformationen) und ist normalerweise verzichtbar.
Quelle: Oracle man pages - [[https://docs.oracle.com/cd/E26502_01/html/E29034/toc.html|section 3: Basic Library Functions]]
* dlopen (gain access to an executable object file): [[https://docs.oracle.com/cd/E26502_01/html/E29034/dlopen-3c.html]]
* ld.so.1 (runtime linker for dynamic objects): [[https://docs.oracle.com/cd/E26502_01/html/E29030/ld.so.1-1.html#REFMAN1ld.so.1-1]]
* lari (link analysis of runtime interfaces): [[https://docs.oracle.com/cd/E26502_01/html/E29030/lari-1.html#scrolltoc]]
----
Stand: 27.09.2019\\
--- //[[feedback.jk-wiki@kreick.de|: Jürgen Kreick]]//
EOF