Frage

Was sind die Vorteile einer reinen Header-Bibliothek und warum sollten Sie sie so schreiben, anstatt die Implementierung in eine separate Datei zu packen?

War es hilfreich?

Lösung

Es gibt Situationen, in denen eine Nur-Header-Bibliothek die einzige Option ist, beispielsweise beim Umgang mit Vorlagen.

Eine reine Header-Bibliothek zu haben bedeutet auch, dass Sie sich keine Gedanken über verschiedene Plattformen machen müssen, auf denen die Bibliothek verwendet werden könnte.Wenn Sie die Implementierung trennen, tun Sie dies normalerweise, um Implementierungsdetails zu verbergen und die Bibliothek als Kombination aus Headern und Bibliotheken zu verteilen (lib, dll's oder .so Dateien).Diese müssen natürlich für alle verschiedenen Betriebssysteme/Versionen kompiliert werden, die Sie unterstützen.

Sie könnten die Implementierungsdateien auch verteilen, aber das würde für den Benutzer einen zusätzlichen Schritt bedeuten – das Kompilieren Ihrer Bibliothek vor der Verwendung.

Dies gilt natürlich a von Fall zu Fall Basis.Beispielsweise nehmen die Nur-Header-Bibliotheken manchmal zu Codegröße & Kompilierungszeiten.

Andere Tipps

Vorteile der Nur-Header-Only-Bibliothek:

  • vereinfacht den Build-Prozess. Sie müssen die Bibliothek nicht erstellen, und Sie müssen die kompilierte Bibliothek nicht während des Verbindungsschritts des Builds angeben. Wenn Sie über eine kompilierte Bibliothek verfügen, möchten Sie wahrscheinlich mehrere Versionen davon erstellen: Einer mit debugging aktiviertem Debugging ist ein weiterer mit optimierter Optimierung aktiviert und möglicherweise noch ein weiterer Abstreifer von Symbolen. Und vielleicht noch mehr für ein Multi-Platform-System.

    Nachteile einer Nur-Header-Bibliothek:

    • größere Objektdateien. Jede Inline-Methode aus der in einiger Quelldatei verwendete Bibliothek ergibt sich auch ein schwaches Symbol, die eine Out-of-Line-Definition in der kompilierten Objektdatei für diese Quelldatei. Dies verlangsamt den Compiler und verlangsamt den Linker. Der Compiler muss all dieses BLOAT generieren, und dann muss Linker es herausfiltern.

    • längere Zusammenstellung. Neben dem oben erwähnten Bloat-Problem dauert die Zusammenstellung länger, da die Header mit einer Header-Only-Bibliothek von inhärent größer sind als eine kompilierte Bibliothek. Diese großen Header müssen für jede Quelldatei analysiert werden, die die Bibliothek verwendet. Ein weiterer Faktor ist, dass die Header-Dateien in einer Header-Onli-Bibliothek, die von den Inline-Definitionen benötigten Header-Dateien sowie die benötigten Header, die die Bibliothek benötigen, als kompilierte Bibliothek erstellt worden sein.

    • mehr verwickelte Zusammenstellung. Sie erhalten viel mehr Abhängigkeiten mit einer Header-Only-Bibliothek, wegen der extra genutzten Grippeticeticetagcodes, die mit einer Header-Only-Bibliothek benötigt werden. Ändern Sie die Implementierung einiger Schlüsselfunktion in der Bibliothek und Sie müssen möglicherweise das gesamte Projekt neu kompilieren. Machen Sie diese Änderung in der Quelldatei für eine kompilierte Bibliothek, und alles, was Sie tun müssen, ist neu kompilieren, dass eine Bibliotheksquelldatei die kompilierte Bibliothek mit dieser neuen Datei aktualisiert und die Anwendung wiederverwertet.

    • härter für den menschlichen Lesen. Auch bei der besten Dokumentation müssen Benutzer einer Bibliothek etabliert, um die Header für die Bibliothek zu lesen. Die Header in einer Header-Only-Bibliothek sind mit Implementierungsdetails gefüllt, die den Verständnis der Schnittstelle einsetzen. Mit einer kompilierten Bibliothek ist alles, was Sie sehen, ist die Schnittstelle und einen kurzen Kommentar zu dem, was die Implementierung tut, und das ist normalerweise alles, was Sie möchten. Das ist wirklich alles, was Sie wollen. Sie sollten keine Implementierungsdaten kennen müssen, um zu wissen, wie die Bibliothek verwendet wird.

Ich weiß, dass dies ein alter Faden ist, aber niemand hat ABI-Schnittstellen oder bestimmte Compiler-Probleme erwähnt. Also dachte ich, ich würde.

Dies basiert im Wesentlichen auf dem Konzept, dass Sie entweder eine Bibliothek mit einem Header schreiben, um an Menschen zu verteilen oder sich wiederzuverwenden, indem Sie alles in einem Header haben. Wenn Sie darüber nachdenken, ein Header- und Quelldateien wiederzuwickeln und diese in jedem Projekt neu zu kompilieren, gilt dies nicht wirklich.

Grundsätzlich, wenn Sie Ihren C ++ - Code kompilieren und eine Bibliothek mit einem Compiler erstellen, versucht der Benutzer, diese Bibliothek mit einem anderen Compiler oder einer anderen Version desselben Compilers zu verwenden, dann erhalten Sie aufgrund von Binärnern Linkerfehler oder seltsames Laufzeitverhalten Inkompatibilität.

Beispielsweise ändern die Compiler-Anbieter häufig ihre Implementierung des STL zwischen den Versionen. Wenn Sie eine Funktion in einer Bibliothek haben, die einen STD :: -Vektor akzeptiert, erwartet es, dass die Bytes in dieser Klasse in der Art und Weise angeordnet werden, wie sie angeordnet wurden, wenn die Bibliothek zusammengestellt wurde. Wenn der Anbieter in einer neuen Compiler-Version Effizienzsteigerungen an STD :: Vector vorgenommen hat, sieht der Code des Benutzers die neue Klasse, die möglicherweise eine andere Struktur aufweisen und diese neue Struktur in Ihre Bibliothek gibt. Alles geht von dort bergab ... Aus diesem Grund wird empfohlen, Stl-Objekte nicht über Bibliotheksgrenzen zu bestehen. Gleiches gilt für C-Run-Time-Typen (CRT).

Während des Gesprächs über die CRT, Ihre Bibliothek und der Quellcode des Benutzers müssen im Allgemeinen mit demselben CRT verknüpft sein. Mit Visual Studio, wenn Sie Ihre Bibliothek mithilfe des Multithreaded CRT erstellen, aber die Benutzerverbindungen gegen den Multithreaded-Debug CRT, dann haben Sie Linkprobleme, da Ihre Bibliothek möglicherweise nicht die angezeigten Symbole finden kann. Ich kann mich nicht erinnern, welche Funktion es war, aber für Visual Studio 2015 machte Microsoft eine CRT-Funktion inline. Plötzlich war es in der Kopfzeile nicht die CRT-Bibliothek, sobein für Bibliotheken, die es erwartet hatte, es bei der Link-Zeit zu finden, nicht mehr können, und diese erzeugten Linkfehler. Das Ergebnis war, dass diese Bibliotheken mit Visual Studio 2015 neu kompiliert wurden.

Sie können auch Verknüpfungsfehler oder seltsames Verhalten abrufen, wenn Sie die Windows-API verwenden, aber Sie mit verschiedenen Unicode-Einstellungen für den Bibliotheksbenutzer erstellen. Dies liegt daran, dass die Windows-API Funktionen hat, die entweder Unicode- oder ASCII-Saiten und Makros / Definitionen verwenden, die die korrekten Typen basierend auf den Unicode-Einstellungen des Projekts automagisch verwenden. Wenn Sie eine Zeichenfolge über die Bibliotheksgrenze bestehen, die der falsche Typ ist, dann brechen die Dinge zur Laufzeit. Oder Sie können feststellen, dass das Programm an erster Stelle nicht verbindet.

Diese Dinge trifft auch auf, um Objekte / Typen über Bibliotheksgrenzen von anderen Bibliotheken von Drittanbietern (z. B. einem Eigenvektor oder einer GSL-Matrix) vorbeizusetzen. Wenn sich die 3rd-Partei-Bibliothek den Header zwischen Ihnen zusammensetzt, zwischen dem Sie Ihre Bibliothek und Ihren Benutzerkandel kompilieren, wird der Code kompiliert, dann bricht die Dinge auf.

Grundsätzlich, um sicher zu sein, die einzigen Dinge, die Sie über Bibliotheksgrenzen bestehen können, werden in Typen und einfachen alten Daten (POD) eingebaut. Idealerweise sollte jede POD in Strukturen sein, die in Ihren eigenen Headern definiert sind und sich nicht auf den Headern von Drittanbietern verlassen.

Wenn Sie nur eine Header-Bibliothek angeben, wird der gesamte Code mit denselben Compiler-Einstellungen und gegen dieselben Header kompiliert, sodass viele dieser Probleme möglich sind (Angabe der Version von dritten Teilbibliotheken, die Sie und Ihre Benutzer verwendet werden, sind API-kompatibel ).

Es gibt jedoch Negative, die oben erwähnt wurden, beispielsweise die erhöhte Kompilierungszeit. Sie können auch ein Geschäft ausführen, damit Sie möglicherweise nicht alle Ihre Quellcode-Implementierungsdetails an alle Ihre Benutzer übergeben möchten, falls einer von ihnen es stiehlt.

der Haupt-"Nutzen" ist, dass Sie für den Quellcode, so dass Sie den Quellcode liefern müssen Sie werden mit Fehlerberichten auf Maschinen und mit Compilern enden, die Sie haben niemals davon gehört.Wenn die Bibliothek völlig Vorlagen ist, haben Sie nicht viel Auswahl, aber wenn Sie die Wahl haben, ist der Header nur in der Regel arm Engineering-Wahl.(Andererseits bedeutet der Header natürlich nur das Sie müssen kein Integrationsverfahren dokumentieren.)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top