dlopen(3X) dlopen(3X)
NAME
dlopen - Gemeinsam nutzbares Objekt öffnen
SYNTAX
cc [flag ...] file ... -ldl [library ...]
#include <dlfcn.h>
void *dlopen(char *pathname, int mode);
BESCHREIBUNG
dlopen() ist eine der Funktionen, mit denen der Benutzer direkten
Zugriff auf die Möglichkeiten des dynamischen Binders hat. dlopen()
ermöglicht einem laufenden Prozeß den Zugriff auf ein gemeinsam nutz-
bares Objekt. dlopen() liefert als Ergebnis an den Prozeß einen Zeiger
(handle), den der Prozeß in folgenden Aufrufen von dlsym() und
dlclose() verwenden kann. Dieser Wert sollte von dem Prozeß in keiner
Weise interpretiert werden. pathname ist der Pfadname des zu öffnenden
Objektes; es kann sich dabei um einen absoluten Pfad handeln, oder er
kann relativ zum aktuellen Verzeichnis angegeben werden. Ist der Wert
von pathname gleich 0, so macht dlopen() die Symbole in der ursprüng-
lichen Datei a.out und alle Objekte, die zusammen mit a.out zum Zeit-
punkt des Programmstarts geladen werden sowie alle mit dem Modus
RTLDGLOBAL geladenen Objekte über dlsym() verfügbar (siehe HINWEISE,
Nr. 3).
Ein gemeinsam nutzbares Objekt kann andere Objekte angeben, die für
seine korrekte Ausführung "erforderlich" sind. Diese erforderlichen
Objekte werden durch die Einträge DTNEEDED im Bereich .dynamic des
Originalobjektes angegeben. Jedes erforderliche Objekt kann jeweils
andere erforderliche Objekte angeben. Alle derartigen Objekte werden
zusammen mit dem Originalobjekt als ein Ergebnis des Aufrufs von
dlopen() geladen.
Wenn ein gemeinsam nutzbares Objekt in den Adreßraum eines Prozesses
geladen wird, kann es Verweise auf Symbole enthalten, deren Adresse
nicht bekannt ist, bis das Objekt geladen wird. Diese Verweise müssen
aufgelöst werden, bevor auf die Symbole zugegriffen werden kann. Der
Parameter mode steuert, wann diese Auflösung stattfindet. Folgende
Werte sind möglich:
RTLDLAZY In diesem Modus werden lediglich die Verweise auf Datensym-
bole beim Laden des Objektes aufgelöst. Verweise auf Funk-
tionen werden nicht aufgelöst, bevor die Funktion zum
ersten Mal aufgerufen wird. Dieser Modus sollte zu einem
besseren Systemverhalten führen, da ein Prozeß in der Regel
nicht alle Funktionen eines gegebenen, gemeinsam nutzbaren
Objektes benutzen dürfte.
Seite 1 Reliant UNIX 5.44 Gedruckt 11/98
dlopen(3X) dlopen(3X)
RTLDNOW In diesem Modus werden alle Verweise beim ersten Laden des
Objektes aufgelöst. Dies kann dazu führen, daß einige
Berechnungen umsonst vorgenommen werden, wenn Adressen von
Funktionen aufgelöst werden, die niemals aufgerufen werden.
Der Modus ist jedoch nützlich, wenn Anwendungen sicherstel-
len müssen, daß nach dem Laden eines Objektes alle während
der Laufzeit referenzierten Symbole auch verfügbar sind.
Normalerweise stehen die exportierten Symbole eines von dlopen()
geöffneten Objektes nur den Objekten direkt zur Verfügung, die als
Ergebnis desselben Aufrufs von dlopen() geladen wurden. Wenn das Modu-
sargument logisch über ein or mit dem Wert RTLDGLOBAL verbunden ist,
stehen jedoch die exportierten Symbole aller Objekte, die über diesen
Aufruf von dlopen() geladen wurden, direkt allen anderen von dlopen()
geöffneten Objekten zur Verfügung.
Wenn der dynamische Binder nach Symbolen sucht, um einen Verweis in
einem der Objekte aufzulösen, die er lädt, sucht er in den Symbolta-
bellen der Objekte, die er bereits geladen hat. Er verwendet das erste
Vorkommen des Symbols, das er findet. Als erstes Objekt wird a.out
durchsucht. Anschließend wird die Liste von a.out mit den erforderli-
chen Objekten in der im Bereich .dynamic von a.out angegebenen Reihen-
folge durchsucht. Danach wird die Liste zweiter Ebene der erforderli-
chen Einträge durchsucht usw. Nachdem alle beim Programmstart gelade-
nenen Einträge durchsucht wurden, durchsucht der dynamische Binder
alle Objekte, die als Ergebnis eines Aufrufs von dlopen() geladen wur-
den (hierbei werden die zuvor genannten Regeln für RTLDGLOBAL einge-
halten). Für jede Gruppe wird zuerst das Objekt durchsucht, das für
dlopen() angegeben wurde, dann wird die Liste der Objekte der Reihe
nach durchsucht, die für dieses Objekt erforderlich sind. Danach wer-
den die erforderlichen Einträge der zweiten Ebene durchsucht usw. Da
ein Objekt nur einmal geladen wird und in der Liste der erforderlichen
Objekte eine beliebige Anzahl von Objekten angezeigt werden kann, kann
ein Objekt, das mit einem Aufruf von dlopen() oder beim Programmstart
geladen wurde, vor den für den aktuellen Aufruf von dlopen() geladenen
Objekten durchsucht werden, auch wenn es sich in einer Kette von
Abhängigkeiten für das Objekt befindet, das momentan von dlopen()
geöffnet ist.
ERGEBNIS
Wenn pathname nicht gefunden wird, nicht zum Lesen geöffnet werden
kann, kein gemeinsam nutzbares Objekt ist, oder wenn während der Bear-
beitung oder während des Ladens von pathname oder während der Auflö-
sung seiner symbolischen Verweise ein Fehler auftritt, gibt dlopen()
den Wert NULL als Ergebnis zurück. Genauere Informationen über die
Fehlerursachen stehen über die Funktion dlerror() zur Verfügung.
Seite 2 Reliant UNIX 5.44 Gedruckt 11/98
dlopen(3X) dlopen(3X)
HINWEISE
1. Wenn bei der Erstellung von pathname andere Objekte zusammen mit
pathname gebunden wurden, so werden diese Objekte automatisch durch
dlopen() geladen. Der Suchpfad, der für die Suche nach pathname und
anderen erforderlichen Objekten verwendet wird, entspricht dem
Suchpfad, der auch von der Laufzeit-Ladefunktion eingesetzt wird.
Im einzelnen wird nach pathname an folgenden Stellen gesucht:
a) In dem durch pathname angegebenen Verzeichnis, sofern es sich
nicht um einen einfachen Dateinamen handelt (das heißt, wenn die
Angabe einen Schrägstrich (/) enthält). In diesem Fall wird nur
die Datei durchsucht; die unten aufgeführten Schritte b) bis d)
werden ignoriert.
b) In jedem Pfad, der über die Umgebungsvariable LDRUNPATH ange-
geben ist; diese Variable wurde beim Binden der ausführbaren
Datei gesetzt [siehe ld(1)].
c) In jedem Verzeichnis, das durch die Umgebungsvariable
LDLIBRARYPATH bzw. LDLIBRARY64sPATH angegeben ist.
Diese Umgebungsvariablen sollten eine Liste mit durch Doppel-
punkte voneinander getrennten Verzeichnissen im gleichen Format
wie auch die Umgebungsvariable PATH enthalten [siehe sh(1)].
32-Bit-Programme überprüfen nur die Variable LDLIBRARYPATH,
LDLIBRARY64sPATH wird ignoriert. 64-Bit-Programme überprüfen
statt dessen die Variable LDLIBRARY64sPATH, wenn diese gesetzt
ist; in diesem Fall wird LDLIBRARYPATH ignoriert. Wenn
LDLIBRARY64sPATH nicht gesetzt ist, überprüfen 64-Bit-Pro-
gramme die Variable LDLIBRARYPATH.
Beide Variablen werden ignoriert, wenn der Prozeß mit setuid()
oder setgid() ausgeführt wird [siehe exec(2)].
d) In den vorgegebenen Suchpfaden. Hierbei handelt es sich um
/lib:/usr/lib:/usr/lib/cmplrs/cc für 32-Bit-Programme und
/lib64s:/usr/lib64s:/usr/lib64s/cmplrs/cc für 64-Bit-Programme.
2. Objekte, die unter demselben absoluten oder relativen Pfad gefunden
werden, können beliebig oft durch dlopen() geöffnet werden. Das
angegebene Objekt wird jedoch nur einmal in den Adreßraum des lau-
fenden Prozesses geladen. Wird dasselbe Objekt jedoch durch zwei
verschiedene Pfadnamen gefunden, kann es auch mehrere Male geladen
werden. Als Beispiel betrachten wir das Objekt
/usr/home/me/mylibs/mylib.so und gehen davon aus, daß
/usr/home/me/workdir das aktuelle Verzeichnis ist.
Seite 3 Reliant UNIX 5.44 Gedruckt 11/98
dlopen(3X) dlopen(3X)
...
void *handle1;
void *handle2;
handle1 = dlopen("../mylibs/mylib.so", RTLDLAZY);
handle2 = dlopen("/usr/home/me/mylibs/mylib.so", RTLDLAZY);
...
Dies führt dazu, daß mylibs.so zweimal für den laufenden Prozeß
geladen wird. Andererseits wird mylibs.so bei Verwendung desselben
Objektes und bei demselben aktuellen Verzeichnis nur einmal gela-
den, wenn LDLIBRARYPATH=/usr/home/me/mylibs ist.
...
void *handle1;
void *handle2;
handle1 = dlopen("mylib.so", RTLDLAZY);
handle2 = dlopen("/usr/home/me/mylibs/mylib.so", RTLDLAZY);
...
3. Objekte, die durch einen einzelnen Aufruf von dlopen() geladen wer-
den, können Symbole voneinander verwenden oder von jedem Objekt,
das zur Startzeit des Programms automatisch geladen wird. Objekte,
die durch einen Aufruf von dlopen() geladen werden, können jedoch
nicht auf Symbole eines Objektes zugreifen, das durch einen anderen
Aufruf von dlopen() geladen wird. Diese Symbole stehen indirekt
durch die Verwendung von dlsym() zur Verfügung (sofern nicht der
Modus RTLDGLOBAL verwendet wird).
Benutzer, die einen Zugriff auf die Symboltabelle von a.out selbst
durch die Verwendung von dlopen(0, mode) anstreben, sollten sich
darüber im klaren sein, daß einige der in a.out definierten Symbole
für den dynamischen Binder möglicherweise nicht zur Verfügung ste-
hen. Die durch ld erstellte Symboltabelle für die Verwendung durch
den dynamischen Binder kann unter Umständen nur eine Teilmenge der
in a.out definierten Symbole enthalten, und zwar genau jene, die
von den gemeinsam nutzbaren Objekten verwendet werden, mit denen
a.out gebunden wurde.
4. Der dynamische Binder steht nur mit der dynamischen Bibliothek libc
zur Verfügung (nicht -dn benutzen).
SIEHE AUCH
cc(1), ld(1), sh(1), exec(2), dlclose(3X), dlerror(3X), dlsym(3X).
Kapitel "Das C-Übersetzungssystem" in Leitfaden und Werkzeuge für die
Programmierung mit C.
Seite 4 Reliant UNIX 5.44 Gedruckt 11/98