====== 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