• Regolamento Macrocategoria DEV
    Prima di aprire un topic nella Macrocategoria DEV, è bene leggerne il suo regolamento. Sei un'azienda o un hosting/provider? Qui sono anche contenute informazioni per collaborare con Sciax2 ed ottenere l'accredito nella nostra community!

Guida [SUPER GUIDA]Usare delle DLL in C++[SUPER GUIDA]

Stato
Discussione chiusa ad ulteriori risposte.

Lore.

Utente Mitico
Autore del topic
14 Settembre 2010
9.244
79
Miglior risposta
0
Bene popolo di sciax2 oggi vi voglio spiegare come usare le DLL, vi dico già che la guida è molto lunga quindi ::emoji_relieved: pacienza.
Una DLL, per definizione, è una libreria a caricamento dinamico (Dynamic Link Library ). In quanto libreria è un file che esporta dati, risorse e codice, visibili al programmatore nel momento in cui questi vengono importati.
Il caricamento effettivo degli elementi importati avviene sempre a runtime (tempo di esecuzione), in due modi fondamentali:
il caricamento (loading) è effettuato prima di utilizzare la risorsa importata per la prima volta
il caricamento avviene subito dopo che la risorsa è stata importata, dunque all'avvio del programma
L'uso delle librerie dinamiche offre diversi vantaggi operativi. Si pensi ad una libreria di esempio che contenga la semplice funzione
Codice:
Perfavore, Entra oppure Registrati per vedere i codici!
Il codice efficiente che svolge il calcolo in questione è ben noto, e la funzione è di uso relativamente frequente. Senza utilizzare librerie, ogni programma che impiega la funzione dovrebbe contenere al suo interno il prototipo ed il codice in forma esplicita.
L'uso della libreria permette la semplice importazione del prototipo, mentre il codice sorgente che implementa la funzione è oscuro al programmatore (la libreria è un file compilato, analogamente al file eseguibile).
Saltano all'occhio diverse proprietà vantaggiose offerte dalle DLL: in primo luogo la modularità, un contenuto della libreria è indipendente da qualsiasi programma; si garantisce quindi la massima portabilità (qualunque programma può utilizzarla semplicemente importando le risorse offerte). Una DLL è importabile anche da un programma scritto con un linguaggio di programmazione diverso da quello con cui è stata complilata, si guadagna quindi in flessibilità.
Una DLL è sempre aggiornabile, se si riscontrano problemi nell'implementazione, errori o banalmente implementazioni migliori, si può riscrivere e ricompilare la sola libreria; per aggiornare ognuno dei programmi che la utilizzano sarà necessario sostituire il solo file DLL chiamato.
Le DLL sono librerie condivise; capita spesso che alcune funzioni molto frequenti, ad esempio le funzioni di sistema, siano richiamate da una parte rilevante di programmi. In questo caso si ha un notevole risparmio di spazio fisico perchè il codice importato è presente in memoria secondaria una sola volta. Senza librerie sarebbe stato obbligatorio avere una copia delle risorse per ognuno dei programmi utilizzatori.
Un programma può richiedere l'esecuzione di un servizio solo per una fase limitata del suo funzionamento. Il caricamento dinamico permette che una funzione di libreria sia caricata e rilasciata a tempo di esecuzione, in questo modo si può razionalizzare ed ottimizzare l'utilizzo delle risorse, in particolar modo nei casi più critici in cui si dispone di risorse limitate.
Infine si noti la protezione del codice: il fatto che la DLL sia compilata garantisce al programmatore la possibilità di diffondere il suo prodotto, ad esempio una funzione, facendo in modo che l'utilizzatore possa impiegarlo senza conoscere l'implementazione, che può essere quindi tenuta segreta.
Struttura di una DLL
Una DLL ha una struttura analoga ad un file eseguibile, suddivisibile in tre sezioni principali come esposto in figura.
Quando la libreria viene caricata è eseguito immediatamente il codice relativo all' Entry Point: la funzione DllMain (un file EXE ha come entry point la funzione Main).
Il resto del file è costituito da elementi esportati, comunemente funzioni, che il programmatore può importare direttamente ed indipendentemente dal programma principale.
Contenuto di una DLL
Una DLL può contenere:
L' Entry Point
In Win32 tutte le librerie di collegamento dinamico (DLL) possono contenere una funzione di punto di ingresso facoltativa, generalmente denominata DllMain, chiamata per inizializzazione e terminazione. Ciò consente l'opportunità di assegnare o rilasciare risorse aggiuntive secondo le necessità. Windows chiama la funzione di punto di ingresso in quattro situazioni: aggancio e disconnessione da un processo, connessione e disconnessione dai thread. (Ref:
Perfavore, Entra oppure Registrati per vedere i Link!
) Tramite il valore di un parametro (fdwReason) è possibile risalire a quale degli eventi citati ha scatenato l'attivazione dell'entry point.
Variabili e funzioni esportate
Elementi il cui accesso è consentito ai processi e alle funzioni che importano la libreria. Si tende ad esportare soprattutto le funzioni.
Una DLL C++, se si usa l'ambiente VisualStudio, è esportata ed importata tramite le direttive __declspec(xxx), ma questo verrà visto nel dettaglio in seguito.
Variabili e funzioni private
Elementi il cui accesso è consentito solo a membri interni alla stessa libreria. Solitamente le variabili di libreria sono private.
Risorse Solitamente accodate alla fine del file, le risorse sono elementi di supporto all'applicazione come immagini, icone, video, e file html. Si includono all'interno del file compilato per mantenere una certa compattezza dell'applicazione (pochi file talvolta sono meglio di tanti file, specie nelle applicazioni semplici). Oltre questo si possono nascondere sotto la compilazione file che non si intende distribuire separatamente.
Non sono affatto rari i casi in cui la DLL è un file che contiene solo risorse (si pensi alle librerie di icone di sistema di Windows).
Ogni processo che utilizza la stessa DLL dispone di una propria copia delle variabili globali esportate.
Oltre questo fatto, di norma in una libreria è buona cosa che il codice sia condiviso in "read only" e che le variabili non siano condivise (questo implica l'esistenza di una copia delle variabili per ognuno dei processi utilizzatori).
Questo fatto non è obbligatorio; un programmatore con esigenze particolari può effettuare (a suo rischio) scelte differenti.
Esportazione di una DLL in Microsoft VisualStudio
All'interno di una DLL le funzioni esportate si distinguono dalla normali funzioni per via della specifica dichiarazione.
Il modo "standard" (proposto da Microsoft) per la semplice esportazione di una DLL prevede la creazione di una define condizionale come indicato nell'esempio.
Una volta creata la direttiva si possono dichiarare le variabili e le funzioni che si intendono esportare grazie alla stessa.
Codice:
Perfavore, Entra oppure Registrati per vedere i codici!
In VisualStudio, per indicare il tipo d'uso delle funzioni si usa la direttiva __declspec(dllexport), la quale non è standard C++.
Similarità e differenze tra DLL e applicazioni

Le DLL e le applicazioni hanno in comune tra loro il fatto che entrambi sono moduli eseguibili di un programma. Nonostante questo differiscono tecnicamente in vari aspetti. L'utente medio noterà senza dubbio la differenza più evidente: le DLL non sono programmi direttamente eseguibili mentre le applicazione EXE si.
Il sistema ed il programmatore invece osservano, oltre che certamente la prima, altre due differenze fondamentali:
Un'applicazione può essere eseguita contemporaneamente in più istanze, una stessa libreria è istanziata una sola volta;
Un'applicazione può contenere uno stack, una memoria globale, una coda di messaggi ed handle a file.
Creazione di una DLL in Microsoft VisualStudio
Una DLL come gia visto ha una struttura simile al file eseguibile. I contenuti (in sostanza codice e risorse) sono di tipo analogo.
Un progetto DLL, la cui creazione è possibile attraverso la voce di menù new avrà dunque un aspetto assolutamente simile al classico progetto di una normale applicazione.
A livello pratico , tralasciando la definizione delle risorse che tra l'altro è gestita per via grafica dall'IDE allo stesso modo dei progetti EXE, riporto un esempio sui principali elementi che i progetti DLL possono contenere:
Entry point:
Codice:
Perfavore, Entra oppure Registrati per vedere i codici!
Funzione generica esportata:
Codice:
Perfavore, Entra oppure Registrati per vedere i codici!
Funzione generica privata:
Codice:
Perfavore, Entra oppure Registrati per vedere i codici!
Importazione di una DLL in Microsoft VisualStudio

Una funzione di libreria si importa mediante la direttiva non standard __declspec(dllimport).
Codice:
Perfavore, Entra oppure Registrati per vedere i codici!
L'utilizzo di __declspec(dllimport) è facoltativo nelle dichiarazioni di funzioni, ma consente al compilatore di produrre un codice più efficiente. È necessario utilizzare __declspec(dllimport) per consentire all'eseguibile che importa di accedere agli oggetti e ai simboli pubblici della DLL.
Compilazione e caricamento di una DLL

La fase di compilazione di una DLL, la quale prevederebbe diversamente dal caso dei file eseguibili opzioni particolari del compilatore, è preconfigurata automaticamente in VisualStudio che sceglie le opzioni coerentemente col tipo di progetto con cui si lavora. La libreria compilata puo essere caricata in maniere diverse, in modo statico o dinamico.
Caricamento statico (implicito):
Il collegamento implicito a una DLL, prevede il possesso dei seguenti oggetti da parte del creatore del progetto che intende importare la libreria
La libreria vera e propria compilata (.DLL).
Un file header (.h) contenente le dichiarazioni degli elementi esportati. Tutte le classi, le funzioni e i dati dovrebbero essere caratterizzati dalla direttiva: __declspec(dllimport).
Una libreria di importazione, (.LIB), alla quale effettuare il link statico. Quando viene generata la DLL la libreria di importazione è creata dal linker.
Il programma che deve caricare la libreria lo fa in fase di creazione del processo.
Il file .LIB associato alla DLL è collegato al programma in modo statico. Le funzioni della DLL vengono rese disponibili all'interno del programma che carica la libreria mediante mapping automatico.
Caricamento dinamico (esplicito):
Le applicazioni devono effettuare una chiamata a funzione per caricare direttamente la DLL in fase di esecuzione.
La procedura standard consiste nel chiamare le seguenti funzioni in modo opportuno:
LoadLibrary: Carica la DLL e permette di ottenere l'handle necessario a manipolare le risorse offerte dalla libreria.
GetProcAddress: Restituisce un puntatore per ciascuna funzione esportata che l'applicazione intende chiamare. Poiché le applicazioni chiamano le funzioni della DLL tramite un puntatore, il compilatore non genera riferimenti esterni.
FreeLibrary: Rilascia la risorsa impegnata dal sistema dopo avere terminato le operazioni relative alla DLL.
Condivisione dei dati
Il problema della condivisione dei dati tra processi che utilizzano la stessa libreria non può essere risolto banalmente dall'impiego di variabili globali. Infatti per default di queste ne è disponibile una copia per ogni processo che importa la libreria.
La soluzione potrebbe essere quella di allocare le variabili globali in un segmento di memoria condivisa, ma questo sistema pare contorto e poco flessibile per il programmatore.
Comunque ne illustriamo un semplice esempio:
Codice:
Perfavore, Entra oppure Registrati per vedere i codici!
Al fine di risolvere la stessa questione viene incontro un particolare tipo di oggetto kernel chiamato FileMapping, il quale viene dichiarato sovente nella funzione di EntryPoint.
L'istanziatore dedicato CreateFileMapping(...) esegue una creazione condizionale del seguente tipo:
Se l'oggetto non è stato ancora creato lo alloca e ne restituisce l'handle
Se l'oggetto è stato gia creato viene semplicemente restituito l'handle
Codice:
Perfavore, Entra oppure Registrati per vedere i codici!
Quando tutti i chiamanti la libreria rilasciano la stessa anche l'oggetto FileMapping è rilasciato.
Guida finita :emoji_slight_smile:
Fonte:Mrwebmaster
Alla prossima.


 
Riferimento: [SUPER GUIDA]Usare delle DLL in C++[SUPER GUIDA]

Interessante,grazie :emoji_smiley: Mi serve.
 
Riferimento: [SUPER GUIDA]Usare delle DLL in C++[SUPER GUIDA]

Ciao,

sicuramente questo metodo è ottimale per le dll, io utilizzo un altro metodo, e ve lo posto.
Tutto ciò può essere racchiuso da un semplice void, ovvero nel quale incorporeremo le funzione per il nostro progetto.

Esempio pratico:
Codice:
Perfavore, Entra oppure Registrati per vedere i codici!
Esecuzione DLL:
Codice:
Perfavore, Entra oppure Registrati per vedere i codici!
Ciò è utilizzato nei metodi di hacking per rendere più facile la procedura di 'costruzione' della dll, come nel mio caso.

Tornando in argomento, non posso che dirti: ottimo metodo, ben definito. :emoji_slight_smile:
 
Riferimento: [SUPER GUIDA]Usare delle DLL in C++[SUPER GUIDA]

Bravo molto utile rnigrazio ;) Mi serviva prp :emoji_smiley:
 
Riferimento: [SUPER GUIDA]Usare delle DLL in C++[SUPER GUIDA]

Bella guida, chiara e concisa per quanto possibile!
 
Riferimento: [SUPER GUIDA]Usare delle DLL in C++[SUPER GUIDA]

Ottima guida molto dettagliata, Bravo Moto :emoji_smiley:
 
Stato
Discussione chiusa ad ulteriori risposte.