Newsgroup: it.comp.lang.c++
Titolo: come funzionano le .dll e le .lib in c++?

Proveniendo dal .net sto incontrando alcune difficoltà a capire il
concetto di librerie in c++, perchè mi sembra molto diverso.
La prima cosa che ho visto facendo una ricerca sulla rete è l'utilizzo
della direttiva ddlexport-dllimport: in pratica, senza essere più
precisi (anche perchè non posso esserlo per ora), la dll viene
predisposta sin dall'inizio con le funzioni che intende esportare. E
queste posso essere invocate anche da altri linguaggi di
programmazione.
Ma poi ho trovato file .lib. Con la ricerca che ho fatto su google,
francamente, non ci ho capito molto.
Sembrerebbe che mettendo insieme un file .ddl un .lib e un .h, possa
compilare qualsiasi file senza essere in possesso del codice sorgente
(?) e senza "predisporre" il file con le funzioni da esportare.
Mi aiutate a capirci un po' qualcosa?
Grazie a chi lo farà.
      Giuseppe

 (?) e senza "predisporre" il file con le funzioni da esportare.
????
  bye
	av.

 ????
Non mi meraviglio che tu non abbia la domanda. In un certo senso non
l'ho capita nemmeno io. :)
Sono in una fase in cui sto raccogliendo una mole molto grande di
informazioni e sto cercando di trovare una coerenza tra le varie cose
che leggo.
La domanda nasceva dal fatto che su vari tutorial si legge come
configurare il tutto per fare riferimento alle cartelle che contengono
questi tipi di files prima di compilare.
        Giuseppe

(?) e senza "predisporre" il file con le funzioni da esportare.
Il file .h è l'header e contiene i prototipi delle funzioni con le
clausole di import. In realtà è utile solo a chi dovrà linkare la DLL
staticamente. Il file .lib, se ti stai riferendo ad una import
library, è solo una libreria di aggancio. Contiene una tabella di
riferimenti alle funzioni nella DLL perché possano essere agganciate.
Non so comunque a quale fase tu ti riferisca con "compilare", se a
quella di costruzione della DLL o di costruzione del programma che usa
la DLL. Per la prima fase DEVI specificare quali sono le funzioni da
esportare.
Chiarisci meglio i tuoi dubbi.

 essere più necessari?
I sorgenti della libreria non ti servono piu': ce l'hai gia' compilata 
sottoforma di .lib, ed eventualmente .dll.
Gli header (.h) ti servono ancora per poter utilizzare la libreria dal 
tuo programma.
  bye
	av.

On 6 Set, 13:17, Andrea Laforgia

Innanzi tutto vi ringrazio entrambi per la disponibilità!!! :)
Devo cercare di mettere insieme una montagna di  informazioni che ho
raccolto e letto, dimenticando tutto quello che sapevo del .net,
perchè qua cambia tutto.
Nel .net un programmatore può suddividere un progetto in più dll e un
file exe come meglio ritiene.
Ora vorrei capire con il c++ come si fa.
Forse si fa prima a verificare quello che credo di aver capito.
Mi correggi per favore dove sbaglio?
1) se voglio semplicemente ottenere un singolo file eseguibile, il
compilatore fa tutto con gli opportuni files sorgenti .cpp, .h, .c,
ecc.
2) Se voglio utilizzare delle librerie esterne dll, per es. per
suddividere il software in moduli, nel .net il codice è esattamente lo
stesso come se fosse un eseguibile, non cambia niente. Poi se per
esempio, nella dll ci sono classi dichiarate public, queste posso
essere richiamate dall'eseguibile.
Con il c++ mi sembra di aver capito che dalla dll si possono importare
solo le funzioni e non le classi. Almeno in rete non ho trovato niente
che mi facesse pensare al contario.
Altra differenza dobrebbe essere che, se compilo una dll, il codice
cambia eccome. Devo tra l'altro dichiarare le funzioni che voglio
esportare.
In cosa sbaglio in quello che ho scritto?
3) Infine .lib, .dll, .h.
Se qualcuno mi fornisce già questi file posso utilizzarli per
(perdonatemi il termine) per "attingere" codice da utilizzare insieme
a quello che scrivo io per produrre un singolo file eseguibile.
Se devo produrli io, probabilmente il file header lo prendo così
com'è, la .lib mi vado a studiare io come produrlo, ma quello che
vorrei capire è la .dll la produco utilizzando le stesse precauzioni
come nel caso 2).
Sicuramente ci sarà una marea di imprecisioni, ma da qualche parte
bisogna iniziare con il c++.
      Giuseppe

bisogna iniziare con il c++.
Temo però che tu stia imparando dalla parte sbagliata. Le tue
questioni non riguardano strettamente il C++, ma le modalità di
costruzione di librerie specifiche di una piattaforma. Io temo che tu
abbia grossi dubbi sulle fasi di compilazione/linking in generale e ti
consiglio di approfondire questi aspetti prima di affrontare qualcosa
di minimamente più complesso.

On 6 Set, 20:35, Andrea Laforgia

Ok. Grazie ancora.
Sono d'accordo con te.
Il motivo per cui parto dalla parte sbagliata è che ho trovato un open
source molto interessante e prima ancora di imparare a metterci mano,
mi viene istintivo cercare di capire come organizzare i file in uno o
più progetti, come richiamare le librerie, compilare, ecc.
Se per esempio voglio modificare una costante e compilare il tutto per
cambiare un comportamento, per il momento non posso farlo.
Comunque hai ragione tu, devo avere più pazienza e studiarmi meglio la
compilazione/linking.
...e forse accettare più tranquillamente il fatto di non poter fare
delle cose complesse dopo appena due tre giorni di studio di un
linguaggio complesso come il c++.
       Giuseppe

 perchè qua cambia tutto.
Innanzitutto ti consiglio di chiarirti che cosa è un compilatore ed un 
linker: questi due concetti sono fondamentali in C++ ma non hanno un 
analogo nel .NET (vabbè, c'è il compilatore e il JIT, ma fa lo stesso :) )
In seconda istanza, cerca di usare i termini correttamente: in .NET si 
chiamano assembly sia le librerie che gli eseguibili, in C++ il termine 
non esiste e si distingue semplicemente in Librerie (statiche e 
dinamiche) ed eseguibili. E poi i sorgenti.
Fatte queste premesse, i sorgenti vengono compilati e linkati per creare 
eseguibili e librerie. Devi indicare al linker che cosa creare (tramite 
parametri riga di comando o tramite opzioni nell'IDE -- penso tu usi 
Visual Studio). In Visual Studio cambiano leggermente anche i sorgenti, 
mentre in gcc i sorgenti sono sostanzialmente identici.
La differenza tra librerie ed eseguibili sta sinteticamente nel fatto 
che le librerie "esportano" dei simboli, nel senso che possono essere a 
loro volta linkate ad eseguibili o altre librerie, tramite questi 
simboli esportati.
A questo punto, con una libreria sostanzialmente abbiamo (discorso 
limitato al solo windows!):
1) header file .h, cioè le dichiarazioni delle chiamate in C++. Senza di 
questo il compilatore non sa di cosa si sta parlando.
2) File d'importazione .lib, i punti di ingresso delle librerie (ed in 
certi casi le librerie stesse), cioè gli indirizzi dei vari simboli 
esportati dalla libreria. E' usato dal linker per collegare, o in fase 
di linking (link statico) o in fase di runtime (link dinamico) l'oggetto 
che stiamo creando con la libreria importata.
3) libreria vera e propria .dll, che viene collegata (qui solo 
dinamicamente) al file oggetto finale.
In Windows c'è una dissimmetria tra la fase di esportazione dei simboli 
(cioè della creazione della libreria) e la fase di importazione degli 
stessi (linking cioè uso della libreria). Per questo si usano le due 
direttive dllimport e dllexport, solitamente in un unico header file 
(per ragioni di gestione) tramite una macro ( ad esempio DLLAPI ) che 
cambia di significato a seconda della fase d'uso (creazione o linking).
Spero di averti chiarito alcuni dubbi.
Ti invito nuovamente però ad approfondire prima i concetti di base di 
compilazione e linking, poiché, vedo, fai riferimento a .NET che è un 
mondo completamente differente, in cui non è neppure paragonabile fare 
un confronto.


Grazie, molto utili le tue indicazioni.
Soprattutto per non confondere le idee a chi leggerà nel futuro questo
thread su usenet tra un po' di tempo e leggerà quelle che erano i miei
tentativi di interpretare questi concetti nuovi. :)
A dire il vero nel frattempo ero riuscito a capirci molto di più
continuando le mie ricerche e studiando un po' come funziona il
compilatore e il linker [ma non ho avuto il coraggio di rileggere cosa
ho scritto solo qualche giorno fa :) ].
Ho avuto la sensazione che il materiale in rete sul c++ rispetto
al .net tenga meno conto di chi inizia a studiarlo.
Ma forse mi sbaglio, perchè un beginner dovrebbe iniziare a fare altre
cose e sono io che punto subito a cose che quando ho studiato il .net
ho visto solo in un secondo tempo e adesso sono più curioso di capire
subito.
Tutto sommato mi sembra di aver chiarito molte cose: solo su una cosa
ho un dubbio.
E' sbagliato il seguente schema?
[source_code(.h & .cpp) + header_of_library(.h) +
static_library(.lib)] = [1 file .exe o .dll o .lib]
[source_code(.h & .cpp) + header_of_library(.h) +
import_library(.lib)] + [dynamic_library(.dll)] = [1 file .exe o .dll
o .lib]+ [dynamic_library(.dll)]
      Giuseppe

al .net tenga meno conto di chi inizia a studiarlo.
Devi considerare che, normalmente, al C++ si arriva dal C, cioč da un
linguaggio per il quale le fasi di costruzione di codice eseguibile
sono concetti ormai acquisiti da tempo. La piattaforma .NET č
relativamente nuova e quindi la divulgazione in merito insiste su
certi suoi concetti di base.

 certi suoi concetti di base.
Quello che dici sembra convincente.
Di buono per chi inizia però ho trovato questo ottimo sito, che
segnalo:
http://www.learncpp.com/
    Giuseppe