it-swarm.com.de

Wie erstelle ich eine Bibliothek?

Angenommen, ich habe 10 * .hpp- und * .cpp-Dateien, die ich zum Kompilieren eines Codes benötige. Ich weiß, dass ich dieselben Dateien für viele verschiedene Codes benötige. Kann ich mit diesen Dateien ein "Paket" erstellen, mit dem ich einfach schreiben kann?

#include<mypackage>

anstatt

#include"file1.hpp"
#include"file2.hpp"
...
#include"file10.hpp"

Ich würde dann nicht jedes Mal ein Makefile schreiben müssen, wenn ich dieses "Paket" benötige.

Um genauer zu sein, benutze ich Linux.

17
PinkFloyd

Eine Sammlung von CPP-Quellen (H-Dateien und CPP-Dateien) kann in einer "Bibliothek" zusammengefasst werden, die dann in anderen Programmen und Bibliotheken verwendet werden kann. Die Einzelheiten dazu sind plattform- und toolchain-spezifisch. Ich überlasse es Ihnen, die Details zu entdecken. Ich gebe jedoch ein paar Links, die Sie lesen können:

Erstellen einer gemeinsam genutzten und statischen Bibliothek mit dem gnu-Compiler [gcc]

Exemplarische Vorgehensweise: Erstellen und Verwenden einer Dynamic Link Library (C++)

Bibliotheken können in zwei Typen unterteilt werden: Quellcode-Bibliotheken und Binär-Bibliotheken. Es kann auch Hybride dieser beiden Typen geben - eine Bibliothek kann sowohl eine Quell- als auch eine Binärbibliothek sein. Quellcode-Bibliotheken sind einfach das: eine Sammlung von Code, der nur als Quellcode verteilt wird; normalerweise Header-Dateien. Die meisten Boost-Bibliotheken sind von diesem Typ. Binäre Bibliotheken werden zu einem Paket zusammengefasst, das zur Laufzeit von einem Client-Programm geladen werden kann.

Selbst bei binären Bibliotheken (und natürlich bei Quellenbibliotheken) muss dem Benutzer der Bibliothek eine Headerdatei (oder mehrere Headerdateien) zur Verfügung gestellt werden. Dies sagt dem Compiler des Client-Programms, nach welchen Funktionen usw. in der Bibliothek gesucht werden soll. Was Bibliotheksschreiber häufig tun, ist eine einzige Masterheaderdatei, die Deklarationen aller Elemente enthält, die von der Bibliothek exportiert werden, und der Client #include diesen Header. Bei binären Bibliotheken wird das Client-Programm später mit der Bibliothek "verknüpft", wodurch alle im Header genannten Namen in ausführbare Adressen aufgelöst werden.

Berücksichtigen Sie beim Erstellen der clientseitigen Header-Datei die Komplexität. Es gibt viele Fälle, in denen einige Ihrer Kunden nur einige wenige Teile Ihrer Bibliothek verwenden möchten. Wenn Sie eine Master-Header-Datei erstellen, die alles aus Ihrer Bibliothek enthält, werden die Kompilierungszeiten Ihrer Clients unnötig erhöht. 

Ein üblicher Weg, um mit diesem Problem umzugehen, ist die Bereitstellung einzelner Header-Dateien für korrelierte Teile Ihrer Bibliothek. Wenn Sie an Boost eine einzige Bibliothek denken, ist Boost ein Beispiel dafür. Boost ist eine enorme Bibliothek, aber wenn Sie nur die Regex-Funktionalität wünschen, können Sie nur den rexex-bezogenen Header #includeen, um diese Funktionalität zu erhalten. Sie müssen nicht all of Boost einschließen, wenn Sie nur Regex-Sachen benötigen.

Sowohl unter Windows als auch unter Linux können Binärbibliotheken in zwei Typen unterteilt werden: dynamische und statische. Bei statischen Bibliotheken wird der Code der Bibliothek tatsächlich (in Ermangelung eines besseren Begriffs) in die ausführbare Datei des Client-Programms "importiert". Eine statische Bibliothek wird von Ihnen verteilt, diese wird jedoch nur vom Client während des Übersetzungsschritts benötigt. Dies ist praktisch, wenn Sie Ihren Client nicht zwingen möchten, zusätzliche Dateien mit seinem Programm zu verteilen. Es hilft auch, Abhängigkeit Hölle zu vermeiden. Eine dynamische Bibliothek hingegen wird nicht direkt in das Client-Programm "importiert", sondern wird vom Client-Programm dynamisch geladen, wenn es ausgeführt wird. Dies reduziert sowohl die Größe des Client-Programms als auch möglicherweise den Platzbedarf der Discs, wenn mehrere Programme dieselbe dynamische Bibliothek verwenden, die Bibliotheks-Binärdatei jedoch mit dem Client-Programm verteilt und installiert werden muss.

33
John Dibling

Angenommen, "file1.hpp" und "file2.hpp" usw. sind eng miteinander verbunden und werden (fast) immer zusammen verwendet. Dann ist es eine gute Idee, eine "mypacakge.h" zu erstellen, die die Include-Elemente der anderen Komponenten enthält in und aus sich in eine Bibliothek verwandeln - das ist ein ganz anderer Prozess. 

Wenn sie NICHT eng miteinander verwandt sind und/oder zusammen verwendet werden, sollten Sie ein solches "Mega-Include" nicht haben, da es nur eine Reihe von Dingen mit sich bringt, die nicht benötigt werden. 

Um eine Bibliothek zu erstellen, müssen Sie Ihren Code einmal erstellen und entweder eine .lib-Datei oder eine gemeinsam genutzte Bibliothek (DLL- oder .so-Datei) generieren. Die genauen Schritte dazu hängen von dem verwendeten System ab und es ist mir zu kompliziert, um es hier zu erklären. 

Bearbeiten: Zur weiteren Erläuterung: Die gesamte C++ - Bibliothek ist eigentlich eine Bibliotheksdatei oder eine gemeinsam genutzte Bibliotheksdatei [zusammen mit einer Reihe von Header-Dateien, die einen Teil des Codes und die für die Verwendung des Codes in der Bibliothek erforderlichen Deklarationen enthalten]. Sie fügen jedoch <iostream> und <vector> getrennt hinzu - es wäre ziemlich schrecklich, ALLES aus den verschiedenen C++ - Bibliotheksheatern in einem <allcpplibrary> zu integrieren, auch wenn das Tippen wesentlich geringer ist. Es ist in Abschnitte unterteilt, die eine Funktion pro Headerdatei ausführen. Sie erhalten also ein "komplettes" Set aus einer Header-Datei, aber nicht zu viele andere Dinge, die Sie nicht wirklich benötigen. 

1
Mats Petersson

Unter Linux:

g ++ FLAGS -shared -Wl, -soname, libLIBNAME.so.1 -o libLIBNAME.VERSION OBJECT_FILES

woher

FLAGGEN: typische Flaggen (z. B. -g, -Wall, -Wextra usw.)

LIBNAME: Name Ihrer Bibliothek

OBJECT_FILES: Objektdateien, die aus dem Kompilieren von CPP-Dateien resultieren

VERSION: Version Ihrer Bibliothek

0
Claudio

Wenn ein Client alle zehn Header benötigt, um tatsächlich von Ihrem "Paket" (Bibliothek) Gebrauch zu machen, ist das ein ziemlich schlechtes Interface-Design.

Wenn ein Client nur some - Header benötigt, abhängig davon, welche Teile Ihrer Bibliothek verwendet werden, lassen Sie den Client die entsprechenden Header einschließen, sodass nur ein minimaler Satz von Bezeichnern eingeführt wird. Dies hilft bei Umfang, Modularisierung und Kompilierzeiten.

Wenn alles andere fehlschlägt, können Sie einen "Interface-Header" für die externe Verwendung erstellen, der sich von denjenigen unterscheidet, die Sie intern zum Kompilieren Ihrer Bibliothek verwenden. Dies wäre derjenige, der installiert wird und aus den notwendigen Inhalten der anderen Header besteht. (Ich glaube immer noch nicht, dass Sie alles von jeden Header in Ihrer Bibliothek benötigen.)

Ich würde Salgars Lösung entmutigen. Sie entweder haben individuelle Kopfzeilen, oder eine monolithische Kopfzeile. Die Bereitstellung einzelner Kopfzeilen plus einer zentralen, die einfach die anderen einschließt, erscheint mir als ziemlich schlechtes Layout.

Was ich nicht verstehe, ist inwiefern Makefiles dabei mitspielen. Header-Abhängigkeiten sollten von Ihrem Makefile/Build-System automatisch aufgelöst werden, d. H. Es sollte hier keine Rolle spielen, wie Ihre Header-Dateien angeordnet sind.

0
DevSolar

Ja und nein. 

Sie können einen Include-All-Header schreiben, sodass #include "myLib.h" ausreicht, da Sie alle diese Header über den einzelnen Header einschließen. Das bedeutet jedoch nicht, dass das einzelne Include ausreicht, um den Inhalt der 10 '.cpp-Dateien automatisch mit Ihrem Projekt zu verknüpfen. Sie müssen sie in eine Bibliothek kompilieren und diese einzelne Bibliothek (anstelle aller Objektdateien) mit den Projekten verknüpfen, die "myLib.h" verwenden. Bibliotheksbinärdateien werden als statische und dynamische Bibliotheken geliefert. Die Dateien haben in der Regel den Namen .lib und .dll (Windows) bzw. .a und .so (Linux) für statische bzw. dynamische Bibliotheken. 

Wie Sie solche Bibliotheken erstellen und verknüpfen, hängt von Ihrem Build-System ab. Möglicherweise möchten Sie diese Begriffe im Internet lokalisieren.

Eine Alternative ist, die .cpp-Dateien durch Definieren aller Funktionen in den Kopfzeilen zu entfernen. Auf diese Weise müssen Sie die zusätzliche Bibliothek nicht verlinken, aber dies kostet höhere Erstellungszeiten, da der Compiler all diese Funktionen jedes Mal verarbeiten muss, wenn Sie den Header direkt oder indirekt in eine Ihrer Übersetzungseinheiten einfügen.

0
Arne Mertz