Bisher wurden von POSIX die Elementarten unterstützt, die vom Compiler oder durch die Compilerausgabe generiert werden:
| Ausführbare Datei (Typ X) |
| Vom Compiler generiertes Objekt (Typ O) |
| ar-Bibliothek (Typ AR; enthält normalerweise die Typen X und O) |
Nun werden auch so genannte "Shared Objects" unterstützt. Die Bezeichnung "Shared Object" wurde aus UNIX abgeleitet. Alternative Bezeichnungen sind auch "dynamische Bibliothek" oder im Zusammenhang mit UNIX "Shared Library".
Unter einem Shared Object versteht man in POSIX immer folgendes Objekt:
| so-Element (Typ SO; erstellt aus den Typen X, O, AR und SO selbst, sowie aus PLAM-Bibliotheken) |
Beim Generieren eines Shared Object können Bibliotheken (Typ SO und Typ AR sowie Typ PLAM) sowie Dateien mit der Namens-Endung ".o" angegeben werden. Um ausführbare Dateien bei der Generierung verwenden zu können (Objekttyp X), müssen diese entsprechend umbenannt werden (siehe "genso - Shared Object erzeugen").
Unterstützung von Shared Objects in POSIX
Shared Objects werden in POSIX in der Weise unterstützt, dass Objekte zur Laufzeit mittels Overlaytechnik explizit nachgeladen werden können (programmgesteuertes Nachladen). Dazu stehen die Funktionen dlopen(), dlclose(), dlsym(), dlerror() und dladdr() zur Verfügung, siehe Kapitel 2.
Ein automatisches Nachladen wie im klassischen BS2000 ist in POSIX nur für Module des Laufzeitsystems CRTE möglich.
Nicht unterstützt wird die in UNIX angebotene Funktionalität, dass Objekte zur Laufzeit automatisch dazugebunden werden können und dass Shared Coding von mehreren Programmen in einem gemeinsamen Speicherbereich verwendet werden kann.
Aufbau eines Shared Object
Physikalisch handelt es sich bei einem Shared Object um eine ar-Bibliothek, die Objektmodule und eine Beschreibung des Shared Object enthält (= Shared object description). Die Beschreibung des Shared Object ist eine Textdatei in der ar-Bibliothek. Diese Textdatei wird beim Erzeugen des Shared Object (per Kommando genso) generiert.
Diese Datei wird während des dlopen()-Aufrufs wie folgt verarbeitet:
Wenn keine abhängigen Bibliotheken gefunden werden, werden die o-Dateien wie in der Datei angegeben geladen.
Wenn ein abhängiges Shared Object vorhanden ist, wird eine neue Liste erzeugt. Das abhängige Shared Object wird an das Ende dieser Liste gehängt.
Anschließend wird erneut nach dem ersten abhängigen Objekt in der neuen Liste gesucht. Dabei kann es sich um ein abhängiges Objekt des ersten abhängigen Objekts handeln.
Diese Verfahren wird wiederholt, bis alle abhängigen Objekte (und die abhängigen Objekte dieser Objekte usw.) durch o-Dateien ersetzt sind. Überprüfungen vermeiden, dass die Liste unendlich fortgesetzt wird. Die o-Dateien in der Liste werden anschließend wie in der Liste angegeben geladen. Diese Auflösung einer so-Datei wird in der Beschreibung von dlopen() als Dependency ordering bezeichnet (= Abhängigkeitsreihenfolge).
ar-Dateien werden auf die gleiche Weise verwaltet wie o-Dateien, da eine ar-Datei als eine geordnete Liste von o-Dateien betrachtet wird.
Beispiel
Hier ist ein typisches Beispiel für eine solche Beschreibung. Diese Beschreibung gehört zum Beispiel 1 beim Kommando genso (siehe "genso - Shared Object erzeugen").
Shared object description für die Datei libtest21.so:
DLL? /posix315/bachmann/sharedlib/examples/libtest21.so ofile_GM_.o ##### /posix315/bachmann/sharedlib/examples/test21.o ###SO### /posix315/bachmann/sharedlib/examples/libtest22.so libtest22.so ###SO### /posix315/bachmann/sharedlib/examples/libtest23.so libtest23.so -X lang=c
Shared object description für Datei libtest22.so:
DLL? /posix315/bachmann/sharedlib/examples/libtest22.so ofile_GM_.o ##### /posix315/bachmann/sharedlib/examples/test22.o ###SO### /posix315/bachmann/sharedlib/examples/libtest24.so libtest24.so -X lang=c
Shared object description für Datei libtest23.so:
DLL? /posix315/bachmann/sharedlib/examples/libtest23.so ofile_GM_.o ##### /posix315/bachmann/sharedlib/examples/test23.o -X lang=c
Shared object description für Datei libtest24.so:
DLL? /posix315/bachmann/sharedlib/examples/libtest24.so ofile_GM_.o ##### /posix315/bachmann/sharedlib/examples/test24.o -X lang=c
Die Elemente dieses Shared Object sehen bei der Bearbeitung durch dlopen() wie folgt aus.
Objekt libtest21.so:
ofile_GM_.o (libtest21.so) libtest22.so libtest23.so
Objekt libtest22.so:
ofile_GM_.o (libtest22.so) libtest24.so
Objekt libtest23.so:
ofile_GM_.o (libtest23.so)
Objekt libtest24.so:
ofile_GM_.o (libtest24.so)
In einem ersten Schritt wird in der Beschreibung von libtest21.so die Referenz auf libtest22.so durch deren Beschreibung ersetzt. Dadurch ergibt sich folgende Anordnung:
ofile_GM_.o (libtest21.so) ofile_GM_.o (libtest22.so) libtest24.so libtest23.so
Dieses Verfahren wird wiederholt, bis sich am Schluss Folgendes ergibt:
ofile_GM_.o (libtest21.so) ofile_GM_.o (libtest22.so) ofile_GM_.o (libtest24.so) ofile_GM_.o (libtest23.so)
In dieser Reihenfolge werden die Elemente dann geladen.