2009-11-26 4 views
22

Bis vor einiger Zeit dachte ich, eine statische Bibliothek wäre nur eine Sammlung von O-Objekt-Dateien, nur archivieren sie und nicht anders behandelt werden. Aber Verknüpfung mit einem O-Objekt und Verknüpfung mit einer statischen Statik-Bibliothek, die dieses O-Objekt enthält, sind offenbar nicht die gleichen. Und ich verstehe nicht, warum ...Statische Initialisierung und Zerstörung der Globalen einer statischen Bibliothek passiert nicht mit g ++

Lassen Sie uns die folgenden Quellcode-Dateien betrachten:

// main.cpp 
#include <iostream> 
int main(int argc, char* argv[]) { 
    std::cout << "main" << std::endl; 
} 

// object.hpp 
#include <iostream> 
struct Object 
{ 
    Object() { std::cout << "Object constructor called" << std::endl; } 
    ~Object() { std::cout << "Object destructor called" << std::endl; } 
}; 

// object.cpp 
#include "object.hpp" 
static Object gObject; 

Lassen Sie uns zusammenzustellen und um Link und führen diese Code:

g++ -Wall object.cpp main.cpp -o main1 
./main1 
> Object constructor called 
> main 
> Object destructor called 

Der Konstruktor und der Destruktor des globalen gObject-Objekts wird aufgerufen.

Lassen Sie uns nun eine statische Bibliothek aus unserem Code erstellen und verwenden (Link) in einem anderen Programm:

g++ -Wall -c object.cpp main.cpp 
ar rcs lib.a object.o 
g++ -Wall -o main2 main.o lib.a 
./main2 
> main 
  • gobject Konstruktor und Destruktor nicht aufgerufen ... warum?
  • Wie haben sie automatisch angerufen?

Danke.

Antwort

29

.a statische Bibliotheken enthalten mehrere .o, aber sie sind nicht verknüpft, es sei denn, Sie verweisen sie aus der Haupt-App.
.o Dateien Standalone-Link immer.

So .o Dateien im Linker immer ins Innere gehen, referenziert oder nicht, aber von .a Dateien nur referenziert .o Objektdateien sind verknüpft.

Als Hinweis, statische globale Objekte müssen nicht initialisiert werden, bis Sie tatsächlich etwas in der Kompilierungseinheit referenzieren, die meisten Compiler initialisieren sie alle vor main, aber die einzige Voraussetzung ist, dass sie vor jeder Funktion von initialisiert werden Die Übersetzungseinheit wird ausgeführt.

+2

Danke. Es scheint, dass die Verknüpfung mit allen .o-Dateien, die in einem .a enthalten sind, erzwungen werden kann, indem man die Linker-Option -Wl, - whole-archive (oder -Wl, -all_load auf MacOSX) verwendet ... – moala

+1

Siehe auch -force_load für MacOSX – moala

+0

Wird es ein Problem geben, wenn sowohl '1.o' als auch' 2.o' aus 'some.a' zwei globale Variablen mit dem gleichen Namen haben? Können sie in eine ausführbare Datei eingebunden werden (in Betracht gezogen werden Fälle: die globale wird verwiesen/nicht von der ausführbaren Datei verwiesen)? –

Verwandte Themen