Eine statische Bibliothek (.a) ist eine Bibliothek, die direkt in die endgültige ausführbare Datei gelinkt werden kann, die vom Linker produziert wird, sie ist darin enthalten und es besteht keine Notwendigkeit, die Bibliothek in dem System zu haben, wo die ausführbare Datei bereitgestellt wird.
Eine gemeinsam genutzte Bibliothek (.so) ist eine Bibliothek, die verknüpft, aber nicht in die endgültige ausführbare Datei eingebettet ist, also geladen wird, wenn die ausführbare Datei gestartet wird, und in dem System vorhanden sein muss, in dem die ausführbare Datei bereitgestellt wird.
Eine Dynamic Link Library unter Windows (.dll) ist wie eine gemeinsam genutzte Bibliothek (.so) unter Linux, aber es gibt einige Unterschiede zwischen den beiden Implementierungen, die sich auf das Betriebssystem beziehen (Windows vs. Linux):
Eine DLL kann zwei Arten von Funktionen definieren:exportierte und interne. Die exportierten Funktionen sollen von anderen Modulen sowie von der DLL, in der sie definiert sind, aufgerufen werden. Interne Funktionen sollen normalerweise nur innerhalb der DLL aufgerufen werden, in der sie definiert sind.
Ein SO Die Bibliothek unter Linux benötigt keine spezielle export-Anweisung, um exportierbare Symbole anzuzeigen, da alle Symbole für einen abfragenden Prozess verfügbar sind.
Ich habe immer gedacht, dass DLLs und gemeinsam genutzte Objekte nur unterschiedliche Begriffe für dasselbe sind - Windows nennt sie DLLs, während sie auf UNIX-Systemen gemeinsam genutzte Objekte sind, wobei der allgemeine Begriff - dynamisch verknüpfte Bibliothek - beide abdeckt (sogar die Funktion to Das Öffnen einer .so-Datei unter UNIX heißt dlopen()
nach 'dynamische Bibliothek').
Sie werden zwar nur beim Start der Anwendung verknüpft, aber Ihre Vorstellung von der Überprüfung anhand der Header-Datei ist falsch. Die Header-Datei definiert Prototypen, die erforderlich sind, um den Code zu kompilieren, der die Bibliothek verwendet, aber zur Verbindungszeit schaut der Linker in die Bibliothek selbst, um sicherzustellen, dass die benötigten Funktionen tatsächlich vorhanden sind. Der Linker muss die Funktionskörper zum Zeitpunkt des Links irgendwo finden, sonst wird ein Fehler ausgelöst. Dies geschieht AUCH zur Laufzeit, da sich die Bibliothek selbst möglicherweise geändert hat, seit das Programm kompiliert wurde, wie Sie zu Recht darauf hinweisen. Aus diesem Grund ist ABI-Stabilität in Plattformbibliotheken so wichtig, da die ABI-Änderung vorhandene Programme, die mit älteren Versionen kompiliert wurden, beschädigt.
Statische Bibliotheken sind nur Bündel von Objektdateien direkt aus dem Compiler, genau wie diejenigen, die Sie selbst als Teil der Kompilierung Ihres Projekts erstellen, sodass sie auf genau die gleiche Weise eingezogen und an den Linker weitergeleitet werden, und nicht verwendete Bits sind genau so fallen gelassen.
Ich kann die Details von DLLs in Windows näher erläutern, um diese Rätsel für meine Freunde hier im *NIX-Land...
zu klärenEine DLL ist wie eine Shared Object-Datei. Beides sind Abbilder, die vom Programmlader des jeweiligen Betriebssystems in den Speicher geladen werden können. Die Bilder werden von verschiedenen Metadaten begleitet, um Linkern und Loadern dabei zu helfen, die notwendigen Assoziationen herzustellen und die Codebibliothek zu verwenden.
Windows-DLLs haben eine Exporttabelle. Die Exporte können nach Namen oder nach Tabellenposition (numerisch) erfolgen. Die letztgenannte Methode gilt als "alte Schule" und ist viel anfälliger - ein Neuaufbau der DLL und das Ändern der Position einer Funktion in der Tabelle führt zu einer Katastrophe, während es kein wirkliches Problem gibt, wenn die Verknüpfung von Einstiegspunkten nach Namen erfolgt. Vergessen Sie das also als Problem, aber seien Sie sich bewusst, dass es da ist, wenn Sie mit "Dinosaurier"-Code wie Bibliotheken von Drittanbietern arbeiten.
Windows-DLLs werden durch Kompilieren und Verknüpfen erstellt, genau wie Sie es für eine EXE (ausführbare Anwendung) tun würden, aber die DLL soll nicht alleine stehen, genau wie ein SO von einer Anwendung verwendet werden soll, entweder durch dynamisches Laden oder durch Link-Time-Bindung (der Verweis auf das SO ist in die Metadaten der Anwendungsbinärdatei eingebettet, und der Programmlader des Betriebssystems lädt die SOs, auf die verwiesen wird, automatisch). DLLs können auf andere DLLs verweisen, genauso wie SOs auf andere SOs verweisen können.
In Windows stellen DLLs nur bestimmte Einstiegspunkte zur Verfügung. Diese werden als „Exporte“ bezeichnet. Der Entwickler kann entweder ein spezielles Compiler-Schlüsselwort verwenden, um ein Symbol extern sichtbar zu machen (für andere Linker und den dynamischen Loader), oder die Exporte können in einer Moduldefinitionsdatei aufgelistet werden, die zur Linkzeit verwendet wird, wenn die DLL selbst ist erschaffen werden. Die moderne Praxis besteht darin, die Funktionsdefinition mit dem Schlüsselwort zum Exportieren des Symbolnamens zu dekorieren. Es ist auch möglich, Header-Dateien mit Schlüsselwörtern zu erstellen, die dieses Symbol als eines deklarieren, das aus einer DLL außerhalb der aktuellen Kompilierungseinheit importiert werden soll. Schlagen Sie die Schlüsselwörter __declspec(dllexport) und __declspec(dllimport) nach, um weitere Informationen zu erhalten.
Eines der interessanten Features von DLLs ist, dass sie eine Standard-Handler-Funktion „beim Laden/Entladen“ deklarieren können. Immer wenn die DLL geladen oder entladen wird, kann die DLL je nach Fall eine Initialisierung oder Bereinigung durchführen. Dies passt gut dazu, eine DLL als objektorientierten Ressourcenmanager zu haben, wie z. B. einen Gerätetreiber oder eine gemeinsam genutzte Objektschnittstelle.
Wenn ein Entwickler eine bereits erstellte DLL verwenden möchte, muss er entweder auf eine „Exportbibliothek“ (*.LIB) verweisen, die vom DLL-Entwickler erstellt wurde, als er die DLL erstellt hat, oder er muss die DLL explizit zur Laufzeit laden und anfordern Einstiegspunktadresse nach Namen über die Mechanismen LoadLibrary() und GetProcAddress(). Meistens werden DLLs durch das Verknüpfen mit einer LIB-Datei (die einfach die Linker-Metadaten für die exportierten Einstiegspunkte der DLL enthält) verwendet. Dynamisches Laden ist normalerweise für die Implementierung von „Polymorphismus“ oder „Laufzeitkonfigurierbarkeit“ in Programmverhalten reserviert (Zugriff auf Add-Ons oder später definierte Funktionen, auch „Plugins“ genannt).
Die Arbeitsweise von Windows kann manchmal etwas Verwirrung stiften; Das System verwendet die Erweiterung .LIB, um sowohl auf normale statische Bibliotheken (Archive, wie POSIX *.a-Dateien) als auch auf die "Export-Stub"-Bibliotheken zu verweisen, die zum Binden einer Anwendung an eine DLL zur Verbindungszeit erforderlich sind. Man sollte also immer schauen, ob eine *.LIB-Datei eine gleichnamige *.DLL-Datei hat; Wenn nicht, stehen die Chancen gut, dass die *.LIB-Datei ein statisches Bibliotheksarchiv ist und keine Bindungsmetadaten für eine DLL exportiert.