|
|
Lexikon auf Ihrer Homepage |
|
Lexikon als Lesezeichen hinzufügen |
Eine Programmbibliothek bezeichnet in der Programmierung eine Sammlung von Unterprogrammen, die Lösungswege fĂŒr thematisch zusammengehörende Problemstellungen anbieten.
Bibliotheken sind im Unterschied zu Programmen keine eigenstÀndig lauffÀhigen Einheiten, sondern Hilfsmodule, die von Programmen angefordert werden. Programmbibliotheken, die zu kommerziellen Produkten gehören, werden nicht im Quelltext veröffentlicht, da sie meist ein Firmengeheimnis darstellen. Zum Schutz gegen Dekompilieren werden dann oft ein Obfuscator eingesetzt sowie alle Symbole (Variablen- und Sprungadressnamen) entfernt.
Inhaltsverzeichnis |
Quelltextbibliotheken enthalten Sammlungen von Wertedefinitionen, Deklarationen, Funktionen, Klassen, generischen Bestandteilen, usw. (siehe auch: API, C-Standardbibliothek, C++-Standardbibliothek). Im Unterschied zu den anderen Arten von Programmbibliotheken sind die zugehörigen Dateien noch nicht kompiliert, daher der Quelltext im Namen.
Statische und dynamische Bibliotheken sind bereits vorab kompilierter Code.
Eine statische Bibliothek wird nach dem Kompiliervorgang des (Haupt-) Programms durch einen so genannten Linker mit dem Kompilat verbunden â er setzt aus Bibliothek und (Haupt-) Programm ein ausfĂŒhrbares (vollstĂ€ndiges) Programm oder auch eine andere ausfĂŒhrbare Komponente zusammen. Im Detail erzeugt ein Compiler zunĂ€chst aus dem Programmquelltext sogenannte Objekt-Module. Genauso sind (vorher) die Programmquelltexte der Bibliotheksroutinen zu Objekt-Modulen compiliert worden. Vom Linker werden diese Module im nĂ€chsten Schritt zum lauffĂ€higen Programm zusammengefĂŒgt.
Ein optimierender Linker sucht aus den zugeordneten Bibliotheksdateien nur jene Komponenten (Unterprogramme oder Daten) heraus, die vom Programm auch tatsĂ€chlich aufgerufen (referenziert) werden (und fĂŒr die es im Programm keine Implementierung gibt), und hĂ€ngt sie dann an das Programm an. Die so entstehende Datei wird entsprechend gröĂer. Einfache Linker fĂŒgen einfach die komplette Bibliothek hinzu und vergröĂern das Programm dadurch noch mehr.
Dynamische Bibliotheken werden erst bei Bedarf (also nach dem Programmstart des âfertigenâ Anwendungsprogramms) von einem sogenannten Lader oder Linker (von englisch âto linkâ: verknĂŒpfen) in den Arbeitsspeicher geladen. Das geschieht entweder durch eine explizite Anweisung durch das Programm oder implizit durch einen so genannten Laufzeit-Lader, wenn das Programm dynamisch gebunden wurde.
Programme und Bibliotheken, die dynamisch gebunden wurden, mĂŒssen sich um das Laden der benötigten dynamischen Bibliotheken nicht selbst kĂŒmmern. Beim dynamischen Binden werden Bibliothek und Kompilat nur lose verknĂŒpft. Statt die notwendigen Symbole (Variablen- und Sprungadressnamen) zu kopieren, wie beim statischen Binden der Fall, werden sie nur referenziert. Um das Laden der dynamischen Bibliotheken und Suchen der Symbole kĂŒmmert sich ein sogenannter Laufzeit-Binder. Das Auflösen der referenzierten Symbole geschieht entweder sofort (noch vor Start des eigentlichen Programms bzw. beim Laden der Bibliothek) oder faul, bei der ersten Verwendung des Symbols.
Ein typischer Anwendungsfall dafĂŒr, Bibliotheken explizit zu öffnen (die Adresse von Symbolen nach deren Namen zu suchen, um das Symbol zu verwenden), sind Plug-in-Architekturen. Ein weiteres Szenario ist eine optionale Bibliothek, die verwendet wird, falls vorhanden, deren Fehlen aber keinen Fehler darstellt.
Ein Vorteil von dynamischen Bibliotheken ist, dass Programme, die eine dynamische Bibliothek verwenden, von Fehlerbehebungen in der Bibliothek profitieren, ohne neu ĂŒbersetzt werden zu mĂŒssen. Wird beispielsweise ein Fehler in der OpenSSL-Bibliothek gefunden und behoben (die entsprechende Bibliothek wurde ersetzt), so genĂŒgt ein Neustart der Programme, die diese Bibliothek verwenden, um den Fehler auch in diesen Programmen zu beheben.
Da die Dateien, in denen dynamische Bibliotheken gespeichert werden, bei der Benutzung nur gelesen und ausgefĂŒhrt, aber nicht verĂ€ndert werden, können Betriebssysteme mit virtuellem Speicher dynamische Bibliotheken nur einmal laden und in den Adressraum aller verwendenden Prozesse einblenden (âCachingâ). Dies ist beispielsweise bei Multitasking-Systemen vorteilhaft, wenn die Bibliotheken insgesamt sehr groĂ sind und von vielen Prozessen gleichzeitig verwendet werden. (Sollte die DLL interne ZustĂ€nde oder gespeicherte Daten besitzen, kann dies mit Copy-On-Write abgefangen werden.) Viele moderne Betriebssysteme âladenâ die DLLs jedoch nicht sofort, sondern blenden sie direkt von der Festplatte aus ein â sie werden wie paged-out Memory Pages behandelt. Analog werden nicht benötigte Pages, die zu einer DLL gehören, nicht verĂ€ndert wurden und paged-out werden sollen, einfach verworfen â sie sind ja (in der DLL-Datei) schon auf der Festplatte.
Bibliotheken in Programmiersprachen enthalten Dienste, die nicht im Compiler implementiert sind, sondern in der Sprache selbst programmiert sind und mit dem Compiler zusammen oder völlig von ihm getrennt dem Programmierer zur VerfĂŒgung stehen. Im ersten Fall ist die Bibliothek meist in der Sprachbeschreibung festgelegt. Im zweiten Fall spricht man von einer externen Bibliothek.
In der Sprachbeschreibung festgelegte Bibliotheken unterscheiden sich teilweise stark im Umfang.
| Sprache | Teile/Pakete | Header/Klassen | Funktionen/Methoden/Konstruktoren |
|---|---|---|---|
| C (C89+Amendments) | 1 | 18 | 142 |
| C (C99) | 1 | 24 | 482 |
| C++ | 1 | 32 + 18 (C89) | |
| Java 2 (JDK 1.2) | 62 | 1287 | ca 18.000 |
| Java 6 | 202 | 3.850 | 21.881 |
| .Net 1.1 | 8.643 | 84.112 |
Bei den Betriebssystemen Windows (und auch bei OS/2) wird eine Bibliotheksdatei, die dynamisch bindet, als DLL (fĂŒr Dynamic Link Library) bezeichnet. Entsprechend haben diese Dateien meist die Dateiendung .dll. Ihr Dateiformat ist Portable Executable.
Unter Windows kann noch zwischen zwei Arten von DLLs unterschieden werden: Einsprungs-DLLs und ActiveX-DLLs. Einsprungs-DLLs enthalten Funktionen, ActiveX-DLLs enthalten Klassen.
Problematisch ist, dass die DLLs bis Windows 98 und Windows NT 4.0 nicht kontrolliert werden â jedes Programm darf sie austauschen und kann dem Betriebssystem damit möglicherweise Schaden zufĂŒgen. Windows Me, Windows 2000 und die Folgeversionen hingegen verfĂŒgen ĂŒber einen Systemschutz, der auch die DLLs einbezieht.
Ănderungen in DLLs ziehen oft auch Ănderungen im Programm nach sich. Dadurch kommt es leicht zu Versionskonflikten, die oft nur sehr schwer aufzuspĂŒren sind. Eine der Grundideen der DLLs war, Programmcode zwischen mehreren Programmen zu teilen, um so Speicher zu sparen. In der Praxis ist es jedoch dazu gekommen, dass viele Programme bei der Installation DLLs in das Windows-Systemverzeichnis schreiben, die auĂer diesem speziellen Programm kein anderes benutzen kann. AuĂerdem ist die Entwicklung und insbesondere die Anbindung im Vergleich aufwĂ€ndiger als zur statischen Bibliothek.
Praktisch hat dies jedoch keine Bedeutung mehr, da seit mindestens Windows 2000 die allermeisten Applikationen private Bibliotheken[1] mit ihrer Installation mitfĂŒhren, also ein Versionskonflikt im Sinn eines DLL-Konflikts ausgeschlossen ist. Unter Windows haben Bibliotheken, die im Programmordner der Anwendung abgelegt sind, eine höhere PrioritĂ€t als die systemweit verfĂŒgbaren.[2]
Auf unixartigen Betriebssystemen (wie z.B. Linux) ist fĂŒr dynamische Bibliotheken die Bezeichnung shared library (englisch fĂŒr âgemeinsam genutzte Bibliothekâ) gebrĂ€uchlich. Sehr verbreitet ist das Executable and Linking Format (ELF), das Standard-Format unter anderem von Linux, FreeBSD und Solaris.
FĂŒr diese Dateien hat sich die Endung .so (von shared object, âgemeinsam genutztes Objektâ) etabliert. In der Regel folgt dem Bibliotheksnamen noch die Versionsnummer der BinĂ€rschnittstelle (ABI version), so dass mehrere Versionen einer Bibliothek gleichzeitig installiert sein können. Der Laufzeit-Linker wĂ€hlt anhand von Versions-Informationen im auszufĂŒhrenden Programm bzw. in der zu ladenden Bibliothek eine Version mit einer kompatiblen Schnittstelle aus. Da sowohl Programme von Bibliotheken abhĂ€ngen können, als auch Bibliotheken von weiteren Bibliotheken, kann eine Software indirekt von vielen Bibliotheken abhĂ€ngen. Da viele Unixoide Systeme die Bibliotheken zentral fĂŒr Betriebssystem und Applikation zusammen verwalten, existieren Paketverwaltungen, die AbhĂ€ngigkeiten berechnen und benötigte Bibliotheken automatisch installieren können. Beispiele fĂŒr derartige Paketverwaltungs-Systeme sind APT und YUM.
Von welchen Bibliotheken ein Programm direkt abhÀngt, lÀsst sich auf einigen Systemen mit Hilfe des UNIX-Programms ldd(1) herausfinden.
Statische Bibliotheken verwenden den Dateisuffix .a (von âArchivâ) und können mit den UNIX-Programmen ar(1) und nm(1) angesehen und bearbeitet werden. Bei Systemen, die eine Paketverwaltung anbieten, befinden sich statische Bibliotheken oft zusammen mit den Header-Dateien in einem separaten Entwicklungs-Paket.
Bei Software, die in der BinĂ€rversion vertrieben werden soll, beispielsweise kommerzielle Closed-Source-Software oder portable/distributionunabhĂ€ngige Software, muss gewĂ€hrleistet werden, dass alle benötigten Bibliotheken vorliegen. Das Anwendersystem, auf dem diese Software verwendet werden soll, muss dann als kompatible BinĂ€rplattform agieren können. Dies kann folgendermaĂen geschehen:
LD_LIBRARY_PATH ĂŒber ein Skript oder hĂ€ndisch.[5]
$ORIGIN erzeugt werden.[5]
Objekt- und komponentenorienterte AnsĂ€tze können hier realisiert werden, indem in einer Funktion das entsprechende Objekt oder die Komponente instantiiert und zurĂŒckgegeben werden.
Java ist eine eigene Plattform und verwendet ein Bibliothekskonzept, welches nicht an Betriebssysteme gebunden ist. Alle Klassen werden hier dynamisch geladen. Die Bibliotheken sind hierbei die jar-Files oder auch einzelne class-Files. System-jar-Files sucht die virtuelle Maschine (VM) immer relativ zu ihrem eigenem Verzeichnis.
Da die Bibliotheken erst zur Laufzeit geladen werden, kann das erstmalige Aufrufen einer FunktionalitĂ€t etwas lĂ€nger dauern. In Java fĂŒr Echtzeitsysteme, aber auch im Standard-Java kann der Klassenlader durch entsprechende Methodenaufrufe dazu bewegt werden, bestimmte oder alle notwendigen Bibliotheken beim Starten zu laden und sie auch nicht mehr zu entladen, so dass bei der Benutzung kein (weiterer) unerwarteter Zeitverzug entstehen kann.
Bei z/OS werden alle Partitioned Data Sets (PDS) als Bibliotheken bezeichnet. Die einzelnen Elemente dieser Bibliotheken werden allgemein Member oder, wenn es sich um ausfĂŒhrbaren Programmcode handelt, auch Module genannt.
Statische Module mĂŒssen in einer Bibliothek liegen, die dem Linkage Editor als SYSLIB bekanntgegeben wird, dynamische Module werden zur Laufzeit entweder aus der STEPLIB oder aus der JOBLIB geladen und wenn sie hier nicht gefunden werden, aus einer Bibliothek in der LINKLIST.
Beim AmigaOS werden alle Bibliotheken als shared Library verwendet. Sie werden also zur Laufzeit vom Programm beim System angefordert, das dann die Basisadresse der Bibliothek im Speicher (bis OS3.9) oder die entsprechende Schnittstelle (ab OS4.0) zur VerfĂŒgung stellt. Das Programm verwendet dann relative Adressen, um ĂŒber eine Sprungtabelle vor der Basisadresse an die eigentlichen Funktionen (hinter der Basisadresse) zu kommen. Diese Funktionen sind eintrittsinvariant (reentrant).
Selbst bei Ănderungen der Bibliothek sind die bestehenden EintrĂ€ge der Sprungtabellen immer gleich. Es kommen ggf. lediglich neue EintrĂ€ge hinzu am Ende der Tabellen. Somit ist eine AbwĂ€rtskompatibilitĂ€t gegeben.
Als Besonderheit kann bei AmigaOS beim Ăffnen einer Library eine Mindest-Versionsnummer angegeben und so sichergestellt werden, dass eine gewĂŒnschte FunktionalitĂ€t auch wirklich verfĂŒgbar ist. Wird diese Version nicht vorgefunden, kann das aufrufende Programm sicher auf eine einfachere FunktionalitĂ€t, wie sie in der Ă€lteren Library-Version bereitgestellt wird, zurĂŒckschalten.
Bibliotheksdateien tragen die Endung .library und befinden sich meist im Verzeichnis LIBS: der Systempartition. Das Betriebssystem ĂŒberprĂŒft bei der Suche nach einer Bibliothek auch das Programmverzeichnis des anfragenden Programms.