2009-11-26 15 views
22

Fino a qualche tempo fa, pensavo che una libreria statica fosse solo una raccolta di file .o oggetto, semplicemente archiviandoli e non rendendoli gestiti diversamente. Ma il collegamento con un oggetto .o e il collegamento con una libreria .a statica contenente questo oggetto .o non sono apparentemente lo stesso. E io non capisco perché ...Inizializzazione statica e distruzione di globals di una libreria statica non avvenuta con g ++

Prendiamo in considerazione i seguenti file di codice sorgente:

// 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; 

Facciamo compilare ed collegamento ed eseguire questo codice:

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

Il costruttore viene chiamato il distruttore dell'oggetto globale gObject.

Ora creiamo una libreria statica dal nostro codice e utilizzare (link) in un altro programma:

g++ -Wall -c object.cpp main.cpp 
ar rcs lib.a object.o 
g++ -Wall -o main2 main.o lib.a 
./main2 
> main 
  • costruttore e distruttore di GObject non sono chiamati ... perché?
  • Come chiamarli automaticamente?

Grazie.

risposta

29

.a librerie statiche contengono diversi .o ma non sono collegati a meno che non li si fa riferimento dall'app principale.
.o file collegamento standalone sempre.

Quindi i file .o nel linker vanno sempre all'interno, a cui si fa riferimento o no, ma dai file .a si fa riferimento solo ai file oggetto .o collegati.

Come nota, non è necessario inizializzare oggetti statici globali finché non si fa effettivamente riferimento a qualcosa nell'unità di compilazione, la maggior parte dei compilatori li inizializza tutti prima di main, ma l'unico requisito è che vengano inizializzati prima di qualsiasi funzione di l'unità di compilazione viene eseguita.

+2

Grazie. Sembra che il collegamento con tutti i file .o contenuti in una .a possa essere forzato usando l'opzione linker -Wl, - whole-archive (o -Wl, -all_load su MacOSX) ... – moala

+1

Vedi anche -force_load per MacOSX – moala

+0

Ci saranno problemi se entrambi '1.o' e' 2.o' di 'some.a' hanno due variabili globali con lo stesso nome? Possono essere collegati in un unico eseguibile (considerare i casi: il globale è riferito/non riferito dall'eseguibile)? –

Problemi correlati