2011-02-16 18 views
18

Qual è la differenza tra il collegamento ai file include e il collegamento ai file lib?include le directory rispetto al concetto di directory lib domanda

Sono abbastanza nuovo in C/C++ e ho difficoltà a capire la differenza tra l'utilizzo di file include e un file lib statico per chiamare le funzioni. Nella mia mente, i file include hanno funzioni che si possono chiamare proprio come file .lib.

+1

Conoscete la differenza tra la compilazione e il collegamento? Questo potrebbe aiutare a chiarire la risposta. – sstn

risposta

28

In C++ (e C e altri linguaggi simili) una funzione si dice che abbia sia un dichiarazione e una definizione.

La dichiarazione è semplicemente una breve istruzione che dichiara che la funzione esiste e che aspetto ha l'interfaccia. Considerare una funzione di base add che aggiunge due numeri interi insieme. La sua dichiarazione potrebbe essere simile al seguente:

int add(int, int); 

Questo significa che "esiste una funzione add che prende due interi e restituisce un intero". Non specifica cosa effettivamente fa la funzione, nonostante il fatto che possiamo fare una buona congettura basata sul suo nome.

La definizione della funzione è dove definiamo esattamente cosa fa la funzione . Questo potrebbe essere ciò che consideri il codice funzione effettivo. Utilizzando la funzione add come esempio:

int add (int a, int b) 
{ 
    return a + b; 
} 

Così come questo in forma con la tua domanda? Bene, supponiamo di avere un certo numero di funzioni matematiche in math.cpp:

// math.cpp 

int add (int a, int b) 
{ 
    return a + b; 
} 

int sub(int a, int b) 
{ 
    return a - b; 
} 

E supponiamo anche decidiamo di utilizzare alcuni di questi nella nostra funzione principale in main.cpp:

// main.cpp 

#include <iostream> 

int main (int argc, char* argv[]) 
{ 
    std::cout << "1 + 2 = " << add(1, 2) << std::endl; 
    std::cout << "8 - 3 = " << sub(8, 3) << std::endl; 
} 

Se si tenta di compilare main.cpp così com'è, si lamenterà che non sa cosa sono add e sub.Questo perché stai cercando di usarli senza dichiarare che esistono, il che è esattamente ciò per cui è una dichiarazione. Quindi potresti fare quanto segue:

// main.cpp 

#include <iostream> 

int add(int, int); 
int sub(int, int); 

int main (int argc, char* argv[]) 
{ 
    std::cout << "1 + 2 = " << add(1, 2) << std::endl; 
    std::cout << "8 - 3 = " << sub(8, 3) << std::endl; 
} 

Questo funzionerebbe, ma non è molto flessibile. Se aggiungiamo una nuova funzione mul, dobbiamo andare e aggiungere la sua dichiarazione a main.cpp e ogni altro file .cpp che lo utilizza (che è molto lavoro se si hanno molti file .cpp). Quindi ciò che facciamo è invece mettere tutte le dichiarazioni in un singolo file (ad esempio, math.h), quindi dobbiamo solo mantenere l'elenco delle dichiarazioni in un singolo punto. Quindi, includiamo semplicemente math.h in qualsiasi file che utilizza le funzioni matematiche. Questo è lo scopo dei file header (a.k.a. include files).

Questo funziona benissimo, ma potrebbe essere anche meglio. Così com'è, abbiamo un file main.cpp e un file math.cpp, entrambi compilati ogni volta che si compila il programma *. Se le tue funzioni matematiche non cambiano affatto, sicuramente è meglio compilarle una volta e basta inserire le definizioni precompilate nel tuo eseguibile ogni volta che ricomponi main.cpp? Questo è esattamente lo scopo dei file .lib. Contengono il codice precompilato per le definizioni delle funzioni pertinenti. Hai ancora bisogno del file include per farti sapere quali funzioni esistono nella lib.

Lo scopo della fase di collegamento della compilazione è di prendere queste funzioni precompilate e le funzioni appena compilate e riunirle in un unico file eseguibile. In pratica, puoi vedere una lib statica come codice precompilato per un numero di funzioni predefinite, e la sua corrispondenza include il file come strumento per consentire a qualsiasi codice che vuole usare quelle funzioni di sapere quali sono disponibili e quali sono le loro la descrizione è.


* Questo non è strettamente vero, ma è sufficiente per i nostri scopi qui.

+1

Grazie per la spiegazione approfondita. Questo significa che nella creazione di librerie, avremo sempre bisogno di un file .h che faccia riferimento a tutte le funzioni? Ad esempio, se creo myLibrary.lib utilizzando un gruppo di file .cpp e un file .h per dichiarare le mie funzioni, dovrei includere il file .h in qualunque programma io usi la mia libreria per fare riferimento alla libreria come così come il collegamento a myLibrary.lib? – foboi1122

+1

@ foboi1122: hai praticamente avuto l'idea, si. Giusto per chiarire però, farlo in questo modo (cioè con un file include) non è un * requisito * (puoi * semplicemente dichiarare le tue funzioni nel file in cui le utilizzi, come nel mio ultimo esempio di codice), ma lo standard la pratica è usare un include per semplificare la gestione del codice. – Mac

+0

grazie per averlo chiarito. Apprezzo l'aiuto di tutti – foboi1122

2

Includi i file in genere contengono la dichiarazione di un simbolo (una funzione, una variabile). di questo lasciare che il compilatore sa che un nome è definito (nell'intestazione) o altrove (nel caso di dichiarazione):

a.h: 

void a_useful_function(); //declaration 

ma si può anche avere una definizione:

a.h: 

void a_useful_function() 
{ 
    //... do something 
} 

biblioteche sono un accumulo di funzioni che vengono tipicamente esposte dalle intestazioni. L'intestazione è in genere l'interfaccia di una libreria a cui si collegherà.

Esistono tuttavia solo librerie di intestazione che hanno il loro codice di dichiarazioni e definizioni nello stesso file.

Hai menzionato le directory nella tua domanda. Le directory di inclusione sono i luoghi in cui il compilatore cerca di risolvere una direttiva #include "a.h" per il preprocessore.

Ma ci sono anche le directory di libreria in cui il linker cerca le librerie necessarie che di solito forniscono implementazioni (definizioni) alle dichiarazioni nelle intestazioni.

0

di fornire una risposta semplice:

file .lib sono librerie precompilate. se includi un .lib, devi anche includere i file di intestazione .h/hpp, in modo che il compilatore sappia come accedere alle funzioni in .lib.

quando si compila il programma, tutte le funzioni utilizzate dalla lib sono solo collegate, vengono annotate di nuovo.

Problemi correlati