Eine Programmbibliothek (kurz Bibliothek; , kurz ) bezeichnet in der Programmierung eine Sammlung von Unterprogrammen/-routinen, die Lösungswege für thematisch zusammengehörende Problemstellungen anbieten. Bibliotheken sind im Unterschied zu Programmen keine eigenständig lauffähigen Einheiten, sondern sie enthalten Hilfsmodule, die von Programmen angefordert werden.

In erweitertem Sinn gelten als Programmbibliotheken (zum Teil auch „Komponentenbibliothek“ oder „Klassenbibliothek“ genannt) alle Arten von Bibliotheken, die Programmcode(-bestandteile) bereitstellen/enthalten. Insofern unterscheidet man Programmbibliotheken u. a. nach dem Typ des Programmcodes, z. B. Quelltexte, Makros, Object- oder Bytecode, Maschinencode usw. Dementsprechend werden Bibliotheken zu unterschiedlichen Zeitpunkten benutzt, manche nur im Rahmen der Softwareentwicklung (von Werkzeugen der Entwicklungsumgebung), andere nur zur Ausführung von Programmen, wieder andere als Mischform von beiden. Solche Bibliotheken enthalten häufig nicht nur Unterprogramme, sondern Programmcodeteile aller Programm-Typen.

Eine besondere Form von Programmbibliotheken sind Frameworks.

Zugriff Mögliche Zugriffe auf Funktionen einer Programmbibliothek sind durch die Programmierschnittstelle (API) definiert. Dabei handelt es sich um die Gesamtheit der öffentlich verfügbaren Funktionen und Klassen; in Abgrenzung zu den privaten Einheiten der Bibliothek, die nicht zugänglich sind.

Manche proprietären Programmbibliotheken werden nicht im Quelltext veröffentlicht, da sie Firmengeheimnisse darstellen. Zum Schutz gegen Dekompilieren wird dann oft ein Obfuscator eingesetzt sowie alle Symbole (Variablen- und Sprungadressnamen) entfernt.

Speicherungsformen Programmbibliotheken und ihre Inhalte können, abhängig vom Betriebssystem und der Entwicklungsumgebung, in unterschiedlichen Formen und Strukturen gespeichert werden, zum Beispiel: Die Bibliothek ist ein Dateiverzeichnis, ihre Elemente/Komponenten sind einzelne Dateien. Die Bibliothek ist eine Datei, die darin enthaltenen Komponenten werden von den Programmen der Entwicklungsumgebung oder einer speziellen Bibliotheksverwaltungssoftware identifiziert und verarbeitet. Beispiele: Eine sogenannte 'DLL' bei Microsoft oder eine PO-Datei bei IBM-Großrechnern als Bibliothek für Quelltexte, Objektmodule oder ausführbare Lademodule. Unterschiedliche Arten von Bibliotheken werden in einer gemeinsamen Datei verwaltet, die Entwicklungsumgebung kann dies unterscheiden/verarbeiten. Beispiel: Eine 'MDB' bei MS Access enthält Bibliotheken mit Quellcode, Makros, vorübersetztem Pseudocode und anderen Codetypen. Es existiert keine ‚Bibliothek‘, die Komponenten werden als einzelne Dateien gespeichert und ausgeführt, z. B. als „EXE-Dateien“.

Statische Bibliotheken „Statische Bibliothek“ wird eine Programmbibliothek genannt, die Module/Unterprogramme enthält, die durch einen so genannten Linker (von englisch „to link“: verknüpfen) mit dem Kompilat eines anderen Programms verbunden werden. Dabei erzeugt der Linker, in der Regel für ein Hauptprogramm, eine ausführbare Datei oder (je nach Betriebssystem) ein Lademodul in einer Ladebibliothek, in der die von diesem aufgerufenen Module fest (statisch) eingebunden/angehängt sind.

Ein optimierender Linker sucht aus den zugeordneten Objekt-Modulen (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 überschreibende Implementierung gibt) und hängt sie dann an das Programm an. Die so entstehende Datei wird entsprechend größer. Einfache Linker fügen einfach das komplette Objekt-Modul bzw. die komplette Bibliothek hinzu und vergrößern das Programm dadurch noch mehr.

Eine statische Bibliothek ist im Allgemeinen selbst Ergebnis aus Quelltexten, aufgeteilt in mehrere Module, deren Kompilate (Objektmodule) dann vom Linker zu der Bibliothek zusammengefügt wurden.

Kommerzielle Anbieter von Frameworks, die den Quellcode ihrer Funktionen nicht offenlegen möchten, stellen diese den Entwicklern üblicherweise in Form von statischen Bibliotheken und den zugehörigen Header-Dateien bereit. Dadurch haben Software-Entwickler die Möglichkeit, die gebotenen Funktionen in ihren Programmen zu verwenden und in Binärform in ihre Programme einzubauen, ohne dass neben den Definitionen der Quellcode der Funktionen vorliegen muss.

Hardware-Hersteller, die ihre Schnittstellen nicht offenlegen möchten, bieten durch die Bereitstellung statischer Bibliotheken eine Möglichkeit, um Treiber für neue Betriebssystem-Kernel bereitzustellen, ohne selbst bei Updates tätig werden zu müssen. Damit ist es beispielsweise auf Linux-Systemen mit Hilfe vom DKMS möglich, Kernel-Module zu bauen, die die Anforderungen der gegebenen Kernel-Version erfüllen, ohne dass der komplette Quellcode vorliegen muss. Dies betrifft u. a. die Grafiktreiber von NVIDIA.

Dynamische Bibliotheken Aus dynamischen Bibliotheken werden Komponenten erst während der Laufzeit eines Programms über einen sogenannten Lader 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. Heutzutage geschieht dies meist mit Betriebssystem-Unterstützung, da (siehe unten) dynamische Bibliotheken gesondert behandelt werden bzgl. Swapping und Einblendung in den Programm-Adressraum. Der Lader ist somit heute meist zu weiten Teilen eine Betriebssystem-Komponente.

Dynamisch gebundene Programme müssen sich um das Laden der benötigten dynamischen Komponenten 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 aus der Bibliothek) oder lazy (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, müssen Betriebssysteme mit virtuellem Speicher dynamische Bibliotheken nur einmal laden und können sie dann in den Adressraum aller verwendenden Prozesse einblenden. Dies ist beispielsweise bei Multitasking-Systemen vorteilhaft, wenn die Bibliotheken insgesamt sehr groß sind und von vielen Prozessen gleichzeitig verwendet werden. (Sollte die dynamische Bibliothek Zustände oder gespeicherte Daten besitzen, kann dies mit Copy-On-Write abgefangen werden.)

Viele moderne Betriebssysteme laden die dynamischen Bibliotheken jedoch nicht sofort, sondern blenden sie bei Bedarf direkt von der Festplatte aus ein – sie werden wie ausgelagerte Pages behandelt. Analog werden nicht benötigte Pages, die zu einer dynamischen Bibliothek gehören und nicht verändert wurden, einfach verworfen. Bei Bedarf können sie ja aus der Festplatte wieder geladen werden.

Beispiele Programmbibliotheken stellen Komponenten in bestimmten Zusammenhängen bereit, zu denen sie bezüglich ihrer Konstruktion und ihrer Schnittstellen passen (müssen). Dementsprechend gibt es Programmbibliotheken zum Beispiel in folgenden Zusammenhängen: Funktionen des Betriebssystems Weitere System- und Dienstprogramme Teilkomponenten von Entwicklungsumgebungen und Programmiersprachen Komponenten von Standardsoftware-Produkten Komponenten von Individualsoftware, die von den Anwendern in individuell festgelegten Bibliotheken verwaltet werden. GUI-Toolkits zum Erstellen grafischer Benutzeroberflächen

Bibliotheken in verschiedenen Programmiersprachen 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 1.287 ≈ 18.000 Java 6 202 3.850 21.881 .Net 1.0 41 3.581 35.470 .Net 1.1 43 3.818 37.556 .Net 2.0 51 7.419 74.607 .Net 3.0 80 10.639 102.613 .Net 3.5 98 11.417 109.657

Java Java ist eine eigene Plattform und verwendet ein Bibliothekskonzept, welches nicht an das Betriebssystem gebunden ist. Im Grunde wird nicht zwischen Programm und Bibliothek unterschieden. Alle Klassen liegen kompiliert in Form von .class-Dateien vor und werden bei Bedarf geladen. In der Regel sind Bibliotheken, wenn sie aus mehreren Klassen bestehen, in einem Java-Archiv zusammengefasst. Die Java-API selbst liegt ebenfalls in Form von Java-Archiven vor.

Da die einzelnen Klassen einer Bibliothek erst zur Laufzeit geladen werden, kann es bei der ersten Verwendung zu Verzögerungen kommen, bis die Klasse geladen und initialisiert wurde. In Java für Echtzeitsysteme, aber auch in Java SE kann der Klassenlader durch entsprechende Methodenaufrufe bestimmte oder alle notwendigen Bibliotheken beim Starten laden und sie auch nicht mehr entladen, so dass bei der Benutzung keine unerwartete Verzögerung entsteht.

Bibliotheken bei verschiedenen Betriebssystemen Windows Bei den Betriebssystemen Windows und 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 New Executable (16 Bit), Linear Executable (32-Bit-OS/2) oder Portable Executable (32- bzw. 64-Bit-Windows).

Unter Windows wird zwischen mehreren Arten von DLLs unterschieden: Einsprungs-DLL ActiveX-DLL .NET-Assembly (CLI) Windows Metadata (CLI, Dateiendung .winmd) Einsprungs-DLLs enthalten hierbei Funktionen, während ActiveX-DLLs Klassen enthalten.

DLLs bis Windows 98 und Windows NT 4.0 können 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 verfügen über einen Systemschutz, der auch die DLLs einbezieht.

Vorteile Außer Code können auch Daten (zum Beispiel Dialog-Ressourcen) von mehreren Prozessen gemeinsam genutzt werden. DLLs werden häufig statisch verlinkt, können aber auch dynamisch verlinkt werden. Dynamisch heißt hier, dass die DLL explizit vom Programm zur Laufzeit geladen wird und die Funktionen, die sich in der DLL befinden, „per Hand“ mit dem Programm verbunden werden. Dadurch wird es möglich, durch Austauschen der DLL die Funktionalität des Programms zur Laufzeit zu verändern.