C++ Librerie statiche(.lib) e dinamiche(.dll) - Alessandro Barazzuol

C++ Librerie statiche(.lib) e dinamiche(.dll)

In Windows una libreria a collegamento dinamico (DLL) è un tipo di file eseguibile che funge da libreria condivisa di funzioni e risorse. Il collegamento dinamico è una funzionalità del sistema operativo che consente a un eseguibile di chiamare funzioni o utilizzare risorse archiviate in un file separato. Queste funzioni e risorse possono essere compilate e distribuite separatamente dagli eseguibili che le usano. Una DLL non è un file eseguibile autonomo. viene eseguito nel contesto di un’applicazione che lo chiama. Il sistema operativo può caricare la DLL nello spazio di memoria di un’applicazione quando l’applicazione viene caricata (collegamento implicito) o su richiesta in fase di esecuzione (collegamento esplicito). Le DLL semplificano anche la condivisione di funzioni e risorse tra eseguibili. Più applicazioni possono accedere contemporaneamente al contenuto di un’unica copia di una DLL in memoria.

Differenze tra il collegamento dinamico e il collegamento statico

Il collegamento statico copia tutto il codice oggetto in una libreria statica nei file eseguibili che la utilizzano quando vengono compilati. Il collegamento dinamico include solo le informazioni necessarie a Windows in fase di esecuzione per individuare e caricare la DLL che contiene un elemento di dati o una funzione. Quando si crea una DLL, si crea anche una libreria di importazione che contiene queste informazioni. Quando si compila un file eseguibile che chiama la DLL, il linker usa i simboli esportati nella libreria di importazione per archiviare queste informazioni per il caricatore di Windows. Quando il caricatore carica una DLL, la DLL viene mappata allo spazio di memoria dell’applicazione. Se presente, viene chiamata una speciale funzione nella dll DllMain,, per eseguire qualsiasi inizializzazione richiesta dalla dll.

Differenze tra applicazioni e dll

Anche se le dll e le applicazioni sono entrambi moduli eseguibili, si differenziano in diversi modi. Per l’utente finale, la differenza più ovvia è che le dll non sono applicazioni che possono essere eseguite direttamente. Dal punto di vista del sistema, esistono due differenze fondamentali tra le applicazioni e le dll:

  • Un’applicazione può avere contemporaneamente più istanze di in esecuzione nel sistema, mentre una DLL può avere una sola istanza.
  • Un’applicazione può essere caricata come processo che può essere proprietaria di elementi quali uno stack, thread di esecuzione, memoria globale, handle di file e una coda di messaggi, ma una DLL non può.

Vantaggi dell’utilizzo delle dll

Il collegamento dinamico al codice e alle risorse offre diversi vantaggi rispetto al collegamento statico:

  • Il collegamento dinamico consente di risparmiare memoria e di ridurre lo scambio. Molti processi possono utilizzare una DLL simultaneamente, condividendo una sola copia delle parti di sola lettura di una DLL in memoria. Al contrario, ogni applicazione compilata utilizzando una libreria collegata in modo statico dispone di una copia completa del codice di libreria che Windows deve caricare in memoria.
  • Il collegamento dinamico consente di risparmiare spazio su disco e larghezza di banda. Molte applicazioni possono condividere una singola copia della DLL sul disco. Al contrario, ogni applicazione compilata utilizzando una libreria a collegamento statico presenta il codice di libreria collegato alla relativa immagine eseguibile, che utilizza più spazio su disco e impiega una maggiore larghezza di banda per il trasferimento.
  • La manutenzione, le correzioni rapide e gli aggiornamenti della sicurezza possono essere più semplici. Quando le applicazioni usano funzioni comuni in una DLL, fino a quando gli argomenti della funzione e i valori restituiti non cambiano, è possibile implementare correzioni di bug e distribuire gli aggiornamenti alla DLL. Quando le dll vengono aggiornate, le applicazioni che le utilizzano non devono essere ricompilate o ricollegate e utilizzano la nuova DLL non appena viene distribuita. Al contrario, le correzioni apportate nel codice oggetto collegato in modo statico richiedono il ricollegamento e la ridistribuzione di tutte le applicazioni che lo usano.
  • È possibile utilizzare le dll per fornire supporto After-Market. Ad esempio, è possibile modificare una DLL del driver di visualizzazione per supportare una visualizzazione che non era disponibile quando l’applicazione è stata spedita.
  • È possibile usare il collegamento esplicito per individuare e caricare le dll in fase di esecuzione, ad esempio le estensioni dell’applicazione che aggiungono nuove funzionalità all’app senza ricompilarla o ridistribuirla.
  • Il collegamento dinamico rende più semplice supportare le applicazioni scritte in linguaggi di programmazione diversi. I programmi scritti in diversi linguaggi di programmazione possono chiamare la stessa funzione di DLL, purché i programmi seguano la convenzione di chiamata della funzione. I programmi e la funzione DLL devono essere compatibili nei modi seguenti: l’ordine in cui la funzione prevede il push degli argomenti nello stack, se la funzione o l’applicazione è responsabile della pulizia dello stack e se gli argomenti sono registri passati.
  • Il collegamento dinamico fornisce un meccanismo per estendere le classi della libreria MFC. È possibile derivare classi dalle classi MFC esistenti e inserirle in una DLL di estensione MFC per l’utilizzo da parte delle applicazioni MFC.
  • Il collegamento dinamico rende più semplice la creazione di versioni internazionali dell’applicazione. Le dll sono un modo pratico per fornire risorse specifiche delle impostazioni locali, che semplificano la creazione di versioni internazionali di un’applicazione. Anziché spedire molte versioni localizzate dell’applicazione, è possibile inserire le stringhe e le immagini per ogni lingua in una DLL di risorse separata e quindi l’applicazione può caricare le risorse appropriate per le impostazioni locali in fase di esecuzione.

Un potenziale svantaggio nell’uso delle dll è che l’applicazione non è indipendente. dipende dall’esistenza di un modulo DLL separato che è necessario distribuire o verificare come parte dell’installazione.

Procedura dettagliata: Creare e usare una libreria di collegamento dinamico personalizzata (C++)

  • 22/08/2019
  • 21 minuti per la lettura

Questa procedura dettagliata illustra come usare l’IDE di Visual Studio per creare la propria libreria di collegamento dinamico (DLL) scritta in Microsoft C++ (MSVC). Viene quindi illustrato come usare la DLL da un’altra C++ app. Le dll, note anche come librerie condivise nei sistemi operativi basati su UNIX, rappresentano uno dei più utili tipi di componenti di Windows. È possibile usarli come metodo per condividere codice e risorse e per compattare le dimensioni delle app. Le dll possono anche semplificare il servizio e l’estensione delle app.

In questa procedura dettagliata verrà creata una DLL che implementa alcune funzioni matematiche. Si creerà quindi un’app console che usa le funzioni della DLL. Verrà inoltre introdotta un’introduzione ad alcune delle tecniche di programmazione e alle convenzioni utilizzate nelle DLL di Windows.

In questa procedura dettagliata vengono illustrate le seguenti attività:

  • Creare un progetto di DLL in Visual Studio.
  • Aggiungere funzioni e variabili esportate nella DLL.
  • Creare un progetto di app console in Visual Studio.
  • Usare le funzioni e variabili importate dalla DLL nell’app console.
  • Eseguire l’app completata.

Analogamente a una libreria collegata in modo statico, una DLL Esporta variabili, funzioni e risorse in base al nome. Un’app client Importa i nomi per usare tali variabili, funzioni e risorse. Diversamente da una libreria collegata staticamente, Windows connette le importazioni nell’app alle esportazioni in una DLL in fase di caricamento o in fase di esecuzione, invece di farlo in fase di collegamento. Windows richiede informazioni aggiuntive che non fanno parte del modello di compilazione C++ standard per stabilire queste connessioni. Il compilatore MSVC implementa alcune estensioni specifiche di Microsoft per C++ per fornire queste informazioni aggiuntive. Queste estensioni verranno presentate man mano che si procede.

Questa procedura dettagliata crea due soluzioni di Visual Studio: una che compila la DLL e una che compila l’app client. La DLL usa la convenzione di chiamata C. Può essere chiamato da app scritte in altri linguaggi di programmazione, a condizione che la piattaforma, le convenzioni di chiamata e le convenzioni di collegamento corrispondano. L’app client usa il collegamento implicito, mentre Windows collega l’app alla DLL in fase di caricamento. Questo collegamento consente all’app di chiamare le funzioni fornite dalla DLL proprio come le funzioni in una libreria collegata staticamente.

Questa procedura dettagliata non tratta alcune situazioni comuni. Il codice non Mostra l’uso di C++ dll da altri linguaggi di programmazione. Non viene illustrato come creare una DLL di sole risorseo come utilizzare il collegamento esplicito per caricare le dll in fase di esecuzione anziché in fase di caricamento. Se si è certi, è possibile usare MSVC e Visual Studio per eseguire tutte queste operazioni.

Per collegamenti a ulteriori informazioni sulle DLL, vedere Creare DLL C/C++ in Visual Studio. Per ulteriori informazioni sul collegamento implicito e sul collegamento esplicito, vedere determinare il metodo di collegamento da utilizzare. Per informazioni sulla creazione C++ di dll da usare con i linguaggi di programmazione che usano le convenzioni di collegamento del linguaggio c, vedere C++ esportazione di funzioni da usare in eseguibili in linguaggio c. Per informazioni su come creare DLL da usare con i linguaggi .NET, vedere Chiamata di funzioni DLL da applicazioni Visual Basic.

Prerequisiti

  • Un computer che esegue Microsoft Windows 7 o versioni successive. Si consiglia Windows 10 per un’esperienza di sviluppo ottimale.
  • Una copia di Visual Studio. Per informazioni su come scaricare e installare Visual Studio, vedere Installare Visual Studio. Quando si esegue il programma di installazione, assicurarsi che sia selezionato il carico di lavoro Sviluppo di applicazioni desktop con C++ . Non è un problema se il carico di lavoro non è stato installato durante l’installazione di Visual Studio. È possibile eseguire nuovamente il programma di installazione e installarlo ora.
  • Conoscenza dei concetti di base dell’uso dell’IDE di Visual Studio. Se si sono usate app desktop di Windows in precedenza, è probabilmente possibile riuscire a seguire. Per informazioni introduttive, vedere Panoramica delle funzionalità dell’IDE di Visual Studio.
  • Conoscenza delle nozioni di base del linguaggio C++. Non verranno comunque presentate procedure troppo complicate.

Creare il progetto di DLL

In questo set di attività, si crea un progetto per la DLL, quindi si aggiunge codice e si compila il progetto. Per iniziare, avviare l’IDE di Visual Studio e accedere, se è necessario. Le istruzioni variano leggermente a seconda della versione di Visual Studio in uso.Assicurarsi di avere selezionato la versione corretta nel controllo in alto a sinistra della pagina.

Per creare un progetto di DLL in Visual Studio 2019

  1. Sulla barra dei menu scegliere File > Nuovo > Progetto per aprire la finestra di dialogo Crea nuovo progetto.
  2. Nella parte superiore della finestra di dialogo impostare Linguaggio su C++ , impostare Piattaforma su Windows e impostare Tipo di progetto su Libreria.
  3. Dall’elenco filtrato dei tipi di progetto selezionare libreria a collegamento dinamico (dll) , quindi fare clic su Avanti.
  4. Nella pagina Configura nuovo progetto immettere MathLibrary nella casella nome progetto per specificare un nome per il progetto. Lasciare i valori predefiniti per percorso e Nome soluzione . Impostare la soluzione per creare una nuova soluzione. Deselezionare posiziona soluzione e progetto nella stessa directory se è selezionata.
  5. Scegliere il pulsante Crea per creare il progetto.

Quando viene creata la soluzione, è possibile visualizzare i file di progetto e di origine generati nella finestra Esplora soluzioni in Visual Studio.

Soluzione generata in Visual Studio

A questo punto la DLL non fa molto. Successivamente, verrà creato un file di intestazione per dichiarare le funzioni esportate dalla DLL e quindi aggiungere le definizioni di funzione alla DLL per renderla più utile.

Per aggiungere un file di intestazione alla DLL

  1. Per creare un file di intestazione per le funzioni, nella barra dei menu scegliere Progetto > Aggiungi nuovo elemento.
  2. Nel riquadro sinistro della finestra di dialogo Aggiungi nuovo elemento selezionare Visual C++ . Nel riquadro centrale selezionare File di intestazione (.h) . Specificare MathLibrary. h come nome per il file di intestazione.
  3. Scegliere il pulsante Aggiungi per generare un file di intestazione vuoto, che viene visualizzato in una nuova finestra dell’editor.
  4. Sostituire il contenuto del file di intestazione con questo codice:C++Copia// MathLibrary.h - Contains declarations of math functions #pragma once #ifdef MATHLIBRARY_EXPORTS #define MATHLIBRARY_API __declspec(dllexport) #else #define MATHLIBRARY_API __declspec(dllimport) #endif // The Fibonacci recurrence relation describes a sequence F // where F(n) is { n = 0, a // { n = 1, b // { n > 1, F(n-2) + F(n-1) // for some initial integral values a and b. // If the sequence is initialized F(0) = 1, F(1) = 1, // then this relation produces the well-known Fibonacci // sequence: 1, 1, 2, 3, 5, 8, 13, 21, 34, ... // Initialize a Fibonacci relation sequence // such that F(0) = a, F(1) = b. // This function must be called before any other function. extern "C" MATHLIBRARY_API void fibonacci_init( const unsigned long long a, const unsigned long long b); // Produce the next value in the sequence. // Returns true on success and updates current value and index; // false on overflow, leaves current value and index unchanged. extern "C" MATHLIBRARY_API bool fibonacci_next(); // Get the current value in the sequence. extern "C" MATHLIBRARY_API unsigned long long fibonacci_current(); // Get the position of the current value in the sequence. extern "C" MATHLIBRARY_API unsigned fibonacci_index();

Questo file di intestazione dichiara alcune funzioni per produrre una sequenza di Fibonacci generalizzata, dati due valori iniziali. Una chiamata a fibonacci_init(1, 1) genera la familiare sequenza di Fibonacci.

Si notino le istruzioni del preprocessore nella parte superiore del file. Il nuovo modello di progetto per un progetto di **_ dll aggiunge le esportazioni NomeProgetto alle macro del preprocessore definite. In questo esempio, Visual Studio definisce MATHLIBRARY_EXPORTS quando viene compilato il progetto di DLL MathLibrary.

Quando viene definita la macro MATHLIBRARY_EXPORTS, la macro MATHLIBRARY_API imposta il modificatore __declspec(dllexport) sulle dichiarazioni di funzione. Questo modificatore indica al compilatore e al linker di esportare una funzione o una variabile dalla DLL per l’uso da parte di altre applicazioni. Quando MATHLIBRARY_EXPORTS non è definito, ad esempio, quando il file di intestazione viene incluso da un’applicazione client, MATHLIBRARY_API applica il modificatore __declspec(dllimport) alle dichiarazioni. Questo modificatore ottimizza l’importazione della funzione o della variabile in un’applicazione. Per altre informazioni, vedere dllexport, dllimport.

Per aggiungere un’implementazione alla DLL

  1. In Esplora soluzionifare clic con il pulsante destro del mouse sul nodo file di origine e scegliere Aggiungi > nuovo elemento.Creare un nuovo file con estensione cpp denominato MathLibrary. cpp, nello stesso modo in cui è stato aggiunto un nuovo file di intestazione nel passaggio precedente.
  2. Nella finestra dell’editor selezionare la scheda MathLibrary.cpp se è già aperta. In caso contrario, in Esplora soluzionifare doppio clic su MathLibrary. cpp nella cartella file di origine del progetto MathLibrary per aprirlo.
  3. Nell’editor sostituire il contenuto del file MathLibrary.cpp con il codice seguente:C++Copia// MathLibrary.cpp : Defines the exported functions for the DLL. #include "pch.h" // use stdafx.h in Visual Studio 2017 and earlier #include <utility> #include <limits.h> #include "MathLibrary.h" // DLL internal state variables: static unsigned long long previous_; // Previous value, if any static unsigned long long current_; // Current sequence value static unsigned index_; // Current seq. position // Initialize a Fibonacci relation sequence // such that F(0) = a, F(1) = b. // This function must be called before any other function. void fibonacci_init( const unsigned long long a, const unsigned long long b) { index_ = 0; current_ = a; previous_ = b; // see special case when initialized } // Produce the next value in the sequence. // Returns true on success, false on overflow. bool fibonacci_next() { // check to see if we'd overflow result or position if ((ULLONG_MAX - previous_ < current_) || (UINT_MAX == index_)) { return false; } // Special case when index == 0, just return b value if (index_ > 0) { // otherwise, calculate next sequence value previous_ += current_; } std::swap(current_, previous_); ++index_; return true; } // Get the current value in the sequence. unsigned long long fibonacci_current() { return current_; } // Get the current index position in the sequence. unsigned fibonacci_index() { return index_; }

Per verificare che tutto funzioni finora, compilare la libreria di collegamento dinamico. Per compilare, scegliere Compila > Compila soluzione dalla barra dei menu. La DLL e l’output del compilatore correlato vengono inseriti in una cartella denominata debugdirettamente sotto la cartella della soluzione. Se si crea una build di rilascio, l’output viene inserito in una cartella denominata Release. L’output avrà un aspetto simile al seguente:OutputCopia

1>------ Build started: Project: MathLibrary, Configuration: Debug Win32 ------
1>pch.cpp
1>dllmain.cpp
1>MathLibrary.cpp
1>Generating Code...
1>   Creating library C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.lib and object C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.exp
1>MathLibrary.vcxproj -> C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.dll
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========

Congratulazioni, è stata creata una DLL con Visual Studio. Nella prossima sezione si vedrà come creare un’app client che usa le funzioni esportate dalla DLL.

Creare un’app client che usa la DLL

Quando si crea una DLL, si pensi a come può essere usata dalle app client. Per chiamare le funzioni o accedere ai dati esportati da una DLL, il codice sorgente del client deve disporre delle dichiarazioni disponibili in fase di compilazione. Al momento del collegamento, il linker richiede informazioni per risolvere le chiamate di funzione o gli accessi ai dati. Una DLL fornisce queste informazioni in una libreria di importazione, un file che contiene informazioni su come trovare le funzioni e i dati, anziché il codice effettivo. E in fase di esecuzione la DLL deve essere disponibile per il client, in una posizione individuabile dal sistema operativo.

Che si tratti di un utente o di terze parti, il progetto di app client necessita di diverse informazioni per l’uso di una DLL. È necessario trovare le intestazioni che dichiarano le esportazioni DLL, le librerie di importazione per il linker e la DLL. Una soluzione consiste nel copiare tutti questi file nel progetto client. Per le DLL di terze parti che è improbabile vengano modificate durante lo sviluppo del client, questo metodo può rappresentare il modo migliore per usarle. Tuttavia, quando si crea anche la DLL, è preferibile evitare la duplicazione. Se si crea una copia locale di file DLL in fase di sviluppo, è possibile modificare accidentalmente un file di intestazione in una copia ma non in un’altra oppure utilizzare una libreria non aggiornata.

Per evitare codice non sincronizzato, è consigliabile impostare il percorso di inclusione nel progetto client per includere i file di intestazione DLL direttamente dal progetto DLL. Impostare inoltre il percorso della libreria nel progetto client per includere le librerie di importazione DLL dal progetto di DLL. Infine, copiare la DLL compilata dal progetto DLL nella directory di output di compilazione client. Questo passaggio consente all’app client di usare lo stesso codice DLL che si compila.

Per creare un’app client in Visual Studio

  1. Sulla barra dei menu scegliere file > nuovo > progetto per aprire la finestra di dialogo Crea un nuovo progetto .
  2. Nella parte superiore della finestra di dialogo impostare Linguaggio su C++ , impostare Piattaforma su Windows e impostare Tipo di progetto su Console.
  3. Nell’elenco filtrato dei tipi di progetto scegliere App console e quindi scegliere Avanti.
  4. Nella pagina Configura nuovo progetto immettere MathClient nella casella nome progetto per specificare un nome per il progetto. Lasciare i valori predefiniti per percorso e Nome soluzione . Impostare la soluzione per creare una nuova soluzione. Deselezionare posiziona soluzione e progetto nella stessa directory se è selezionata.
  5. Scegliere il pulsante Crea per creare il progetto client.

Viene creato automaticamente un progetto di applicazione console minimo. Il nome del file di origine principale è lo stesso nome del progetto immesso in precedenza. In questo esempio, il file è denominato MathClient.cpp. È possibile compilare il progetto, ma non usa ancora la DLL.

Successivamente, per chiamare le funzioni MathLibrary nel codice sorgente, il progetto deve includere il file MathLibrary. h . È possibile copiare questo file di intestazione nel progetto dell’app client e quindi aggiungerlo al progetto come elemento esistente.Questo metodo può essere una scelta ottimale per le librerie di terze parti. Tuttavia, se si sta lavorando al codice per la DLL e il client allo stesso tempo, i file di intestazione potrebbero non essere sincronizzati. Per evitare questo problema, impostare il percorso delle directory di inclusione aggiuntive nel progetto per includere il percorso dell’intestazione originale.

Per aggiungere l’intestazione DLL al percorso di inclusione

  1. Fare clic con il pulsante destro del mouse sul nodo MathClient in Esplora soluzioni per aprire la finestra di dialogo Pagine delle proprietà.
  2. Nella casella di riepilogo a discesa configurazione selezionare tutte le configurazioni se non è già selezionata.
  3. Nel riquadro sinistro selezionare Proprietà > di configurazioneC/C++ > generale.
  4. Nel riquadro delle proprietà selezionare il controllo elenco a discesa accanto alla casella di modifica Directory di inclusione aggiuntive e quindi scegliere Modifica.
  5. Fare doppio clic nel riquadro superiore della finestra di dialogo Directory di inclusione aggiuntive per abilitare un controllo di modifica. In alternativa, scegliere l’icona della cartella per creare una nuova voce.
  6. Nel controllo di modifica specificare il percorso del file di intestazione MathLibrary.h. È possibile scegliere il controllo con i puntini di sospensione (  ) per passare alla cartella corretta.È anche possibile immettere un percorso relativo dai file di origine client alla cartella che contiene i file di intestazione della DLL.Se sono state seguite le istruzioni per inserire il progetto client in una soluzione separata dalla DLL, il percorso relativo dovrebbe essere simile al seguente:..\..\MathLibrary\MathLibrarySe la DLL e i progetti client si trovano nella stessa soluzione, il percorso relativo potrebbe essere simile al seguente:..\MathLibraryQuando la DLL e i progetti client si trovano in altre cartelle, modificare il percorso relativo in modo che corrisponda. In alternativa, utilizzare il controllo con i puntini di sospensione per cercare la cartella.
  7. Dopo aver immesso il percorso del file di intestazione nella finestra di dialogo directory di inclusione aggiuntive , scegliere il pulsante OK . Nella finestra di dialogo pagine delle proprietà scegliere il pulsante OK per salvare le modifiche.

È ora possibile includere il file MathLibrary.h e usare le funzioni dichiarate nell’applicazione client. Sostituire il contenuto del file MathClient.cpp usando questo codice:C++Copia

// MathClient.cpp : Client app for MathLibrary DLL.
// #include "pch.h" Uncomment for Visual Studio 2017 and earlier
#include <iostream>
#include "MathLibrary.h"

int main()
{
    // Initialize a Fibonacci relation sequence.
    fibonacci_init(1, 1);
    // Write out the sequence values until overflow.
    do {
        std::cout << fibonacci_index() << ": "
            << fibonacci_current() << std::endl;
    } while (fibonacci_next());
    // Report count of values written before overflow.
    std::cout << fibonacci_index() + 1 <<
        " Fibonacci sequence values fit in an " <<
        "unsigned 64-bit integer." << std::endl;
}

Questo codice può essere compilato ma non collegato. Se si compila l’app client adesso, l’elenco errori Mostra diversi errori di LNK2019. Questo perché nel progetto mancano alcune informazioni: Non è stato specificato che il progetto ha ancora una dipendenza dalla libreria MathLibrary. lib . Non è stato indicato al linker come trovare il file MathLibrary. lib .

Per risolvere questo problema, è possibile copiare il file di libreria direttamente nel progetto di app client. Il linker lo troverà e lo userà automaticamente. Tuttavia, se la libreria e l’app client sono in fase di sviluppo, questo potrebbe causare modifiche in una copia non mostrata nell’altra. Per evitare questo problema, è possibile impostare la proprietà dipendenze aggiuntive per indicare al sistema di compilazione che il progetto dipende da MathLibrary. lib. Inoltre, è possibile impostare un percorso di directory di libreria aggiuntivo nel progetto per includere il percorso della libreria originale quando si collega.

Per aggiungere la libreria di importazione DLL al progetto

  1. Fare clic con il pulsante destro del mouse sul nodo MathClient in Esplora soluzioni e scegliere proprietà per aprire la finestra di dialogo pagine delle proprietà .
  2. Nella casella di riepilogo a discesa configurazione selezionare tutte le configurazioni se non è già selezionata. Garantisce che tutte le modifiche alle proprietà siano valide per le compilazioni di debug e di rilascio.
  3. Nel riquadro sinistro selezionare Proprietà > di configurazioneinputdellinker > . Nel riquadro delle proprietà selezionare il controllo elenco a discesa accanto alla casella di modifica Dipendenze aggiuntive e quindi scegliere Modifica.
  4. Nella finestra di dialogo dipendenze aggiuntive aggiungere MathLibrary. lib all’elenco nel controllo di modifica superiore.
  5. Scegliere OK per tornare alla finestra di dialogo Pagine delle proprietà.
  6. Nel riquadro sinistro selezionare Proprietà > di configurazionecollegamento > generale. Nel riquadro delle proprietà selezionare il controllo elenco a discesa accanto alla casella di modifica Directory librerie aggiuntive e quindi scegliere Modifica.
  7. Fare doppio clic nel riquadro superiore della finestra di dialogo Directory librerie aggiuntive per abilitare un controllo di modifica. Nel controllo di modifica specificare il percorso del file MathLibrary.lib. Per impostazione predefinita, si trova in una cartella denominata debug direttamente nella cartella della soluzione dll. Se si crea una build di rilascio, il file viene inserito in una cartella denominata Release. È possibile usare la $(IntDir) macro in modo che il linker possa trovare la dll, indipendentemente dal tipo di compilazione creata. Se sono state seguite le istruzioni per inserire il progetto client in una soluzione separata dal progetto DLL, il percorso relativo dovrebbe essere simile al seguente:..\..\MathLibrary\$(IntDir)Se la DLL e i progetti client si trovano nella stessa soluzione, il percorso relativo dovrebbe essere simile al seguente:..\MathLibrary\$(IntDir)
  8. Dopo aver immesso il percorso del file di libreria nella finestra di dialogo Directory librerie aggiuntive scegliere il pulsante OKper tornare alla finestra di dialogo Pagine delle proprietà. Scegliere OK per salvare le modifiche alle proprietà.

È ora possibile compilare e collegare l’app client correttamente, ma ancora non include tutto ciò che serve per l’esecuzione. Quando il sistema operativo carica l’app, cerca la DLL MathLibrary. Se non riesce a trovare la DLL in determinate directory di sistema, nel percorso di ambiente o nella directory dell’app locale, il caricamento ha esito negativo. A seconda del sistema operativo, verrà visualizzato un messaggio di errore simile al seguente:

Errore dll MathLibrary non trovato

Un modo per evitare questo problema consiste nel copiare la DLL nella directory che contiene il file eseguibile del client come parte del processo di compilazione. È possibile aggiungere un evento di post-compilazione al progetto per aggiungere un comando che copia la dll nella directory dell’output di compilazione. Il comando specificato qui copia la DLL solo se è mancante o è stato modificato. Usa le macro per copiare da e verso i percorsi di debug o di rilascio, in base alla configurazione della build.

Per copiare la DLL in un evento di post-compilazione

  1. Fare clic con il pulsante destro del mouse sul nodo MathClient in Esplora soluzioni e scegliere proprietà per aprire la finestra di dialogo pagine delle proprietà .
  2. Nella casella a discesa Configurazione selezionare Tutte le configurazioni se non è già selezionato.
  3. Nel riquadro sinistro selezionare Proprietà > di configurazioneeventi > di compilazioneevento post-compilazione.
  4. Nel riquadro delle proprietà selezionare il controllo modifica nel campo riga di comando . Se sono state seguite le istruzioni per inserire il progetto client in una soluzione separata dal progetto DLL, immettere questo comando:xcopy /y /d "..\..\MathLibrary\$(IntDir)MathLibrary.dll" "$(OutDir)"Se la DLL e i progetti client si trovano nella stessa directory della soluzione, immettere questo comando:xcopy /y /d "..\MathLibrary\$(IntDir)MathLibrary.dll" "$(OutDir)"
  5. Scegliere il pulsante OK per salvare le modifiche alle proprietà del progetto.

A questo punto l’app client include tutto il necessario per la compilazione e l’esecuzione. Compilare l’applicazione scegliendo Compila > Compila soluzione nella barra dei menu. La finestra di output in Visual Studio dovrebbe avere un aspetto simile a quello dell’esempio seguente, a seconda della versione di Visual Studio:OutputCopia

1>------ Build started: Project: MathClient, Configuration: Debug Win32 ------
1>MathClient.cpp
1>MathClient.vcxproj -> C:\Users\username\Source\Repos\MathClient\Debug\MathClient.exe
1>1 File(s) copied
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========

È stata completata la creazione di un’applicazione che chiama le funzioni nella DLL. Eseguire ora l’applicazione per vederne le funzioni. Sulla barra dei menu scegliere Debug > Avvia senza eseguire debug. Visual Studio apre una finestra di comando in cui eseguire il programma. L’ultima parte dell’output sarà simile al seguente:

Avviare l'app client senza debug

Premere un tasto qualsiasi per chiudere la finestra di comando.

Ora che sono state create una DLL e un’applicazione client, è possibile sperimentarle. Provare a impostare punti di interruzione nel codice dell’app client ed eseguire l’app nel debugger. Vedere cosa accade quando si esegue una chiamata della libreria. Aggiungere altre funzioni alla libreria o scrivere un’altra app client che usa la DLL.

Quando si distribuisce l’app, è necessario distribuire anche le DLL usate. Il modo più semplice per rendere disponibili le DLL compilate o da terze parti è inserirle nella stessa directory dell’app. È noto come distribuzione locale dell’app. Per altre informazioni sulla distribuzione, vedere Deployment in Visual C++.