2009-12-05 2 views
19

Betrachten Sie diesen Code:Warum eine .a-Datei von .o für die statische Verknüpfung erstellen?

eins.c:

#include <stdio.h> 

int one() { 
    printf("one!\n"); 
    return 1; 
} 

zwei.c:

#include <stdio.h> 

int two() { 
    printf("two!\n"); 
    return 2; 
} 

prog.c

#include <stdio.h> 

int one(); 
int two(); 

int main(int argc, char *argv[]) 
{ 
    one(); 
    two(); 

    return 0; 
} 

Ich möchte zusammen, um diese Programme zu verknüpfen. Also ich mache das:

gcc -c -o one.o one.c 
gcc -c -o two.o two.c 
gcc -o a.out prog.c one.o two.o 

Das funktioniert ganz gut.

Oder ich könnte eine statische Bibliothek erstellen:

ar rcs libone.a one.o 
ar rcs libtwo.a two.o 
gcc prog.c libone.a libtwo.a 
gcc -L. prog.c -lone -ltwo 

Also meine Frage ist: Warum würde ich die zweite Version verwenden - das eine, wo ich eine „.a“ ​​Dateien erstellt - anstatt Verknüpfung meines“. o "Dateien? Beide scheinen statisch miteinander zu verknüpfen, gibt es also einen Vorteil oder einen architektonischen Unterschied zwischen den beiden?

Antwort

38

In der Regel sind Bibliotheken Sammlungen von Objektdateien, die in mehreren Programmen verwendet werden können.

In Ihrem Beispiel gibt es keinen Vorteil, aber Sie könnten getan haben:

ar rcs liboneandtwo.a one.o two.o 

Dann wird Ihr Programm Verknüpfung einfacher:

gcc -L. prog.c -loneandtwo 

Es ist wirklich eine Frage der Verpackung. Haben Sie eine Reihe von Objektdateien, die natürlich eine Reihe verwandter Funktionen bilden, die in mehreren Programmen wiederverwendet werden können? Wenn dies der Fall ist, können sie sinnvollerweise in einer statischen Bibliothek archiviert werden, da sonst wahrscheinlich kein Vorteil besteht.

Es gibt einen wichtigen Unterschied im letzten Verbindungsschritt. Alle Objektdateien, die Sie verknüpft haben, werden in das endgültige Programm aufgenommen. Objektdateien, die sich in Bibliotheken befinden, werden nur einbezogen, wenn sie dabei helfen, nicht definierte Symbole in anderen Objektdateien aufzulösen. Ist dies nicht der Fall, werden sie nicht mit der endgültigen ausführbaren Datei verknüpft.

2

Technisch ist das Ergebnis genau das gleiche. Normalerweise erstellen Sie Bibliotheken für Utility-Funktionen. Anstatt den Linker mit Dutzenden von Objektdateien zu versorgen, müssen Sie lediglich die Bibliothek verknüpfen.

Übrigens macht es absolut keinen Sinn, eine .a-Datei zu erstellen, die nur eine .o-Datei enthält.

+2

Das Ergebnis ist normalerweise sehr unterschiedlich. Es ist zufällig dasselbe in diesem erfundenen Beispiel. – UncleO

1

Der Hauptvorteil ist, wenn Sie verknüpfen müssen, können Sie nur eine Bibliothek anstelle aller separaten Objektdateien angeben. Es hat auch einen kleinen Vorteil, die Dateien zu verwalten und sich mit einer Bibliothek anstatt mit einer Reihe von Objektdateien zu beschäftigen. Dies führte auch zu einer erheblichen Einsparung von Speicherplatz, aber die aktuellen Festplattenpreise machen dies weniger wichtig.

2

Sie können eine Sammlung von Dateien in eine Archivdatei (.a) zur späteren Wiederverwendung ablegen. Die Standardbibliothek ist ein gutes Beispiel.

Manchmal ist es sinnvoll, große Projekte in Bibliotheken zu organisieren.

12

Der Unterschied wäre in der Größe der ausführbaren Datei, obwohl vielleicht nicht für Ihr Beispiel.

Bei der Verknüpfung mit einer Bibliothek werden nur die von der ausführbaren Datei verwendeten Bits einbezogen. Wenn Sie eine Objektdatei verknüpfen, nehmen Sie die ganze Sache.

Zum Beispiel, wenn Ihre ausführbare Datei jede mathematische Funktion in der Mathematikbibliothek enthalten müsste, wenn Sie nur eine verwenden, wäre sie viel größer als sie sein müsste und viel ungenutzten Code enthalten würde.

Es ist interessant, dies mit dem dynamischen Verknüpfungsmodell von Windows zu vergleichen. Dort muss das Betriebssystem alle Dlls (dynamisch verknüpfte Bibliotheken) vollständig laden, die Ihre ausführbare Datei verwendet, was zu einem Aufblähen im RAM führen könnte. Der Vorteil eines solchen Modells besteht darin, dass Ihre ausführbare Datei selbst kleiner ist und die verknüpften Dlls bereits im Speicher vorhanden sind und von einer anderen ausführbaren Datei verwendet werden, sodass sie nicht erneut geladen werden müssen.

Bei der statischen Verknüpfung werden die Bibliotheksfunktionen für jede ausführbare Datei separat geladen.

0

Immer wenn ich diese Frage gestellt werde (von freshers in meinem Team), "warum (oder manchmal sogar ein 'was ist') ein .a?", Verwende ich die folgende Antwort, die .zip als Analogie verwendet.

"Ein dotAy ist wie eine Zip-Datei von allen dotOhs, die Sie während der Erstellung Ihrer exe/lib verlinken möchten. Einsparungen auf Speicherplatz, und außerdem müssen Namen aller beteiligten dotOhs nicht eingegeben werden."

Bisher schien dies zu verstehen. ;)

Verwandte Themen