Regole e limitazioni generali
Sezione specifica Microsoft
Se si dichiara una funzione o un oggetto senza l'attributo
dllimport
odllexport
, la funzione o l'oggetto non viene considerato parte dell'interfaccia DLL. Di conseguenza, la definizione della funzione o dell'oggetto deve essere presente in tale modulo o in un altro modulo dello stesso programma. Per rendere la funzione o l'oggetto parte dell'interfaccia DLL, è necessario dichiarare la definizione della funzione o dell'oggetto nell'altro modulo comedllexport
. In caso contrario, viene generato un errore del linker.Se si dichiara una funzione o un oggetto con l'attributo
dllexport
, la relativa definizione deve essere visualizzata in un modulo dello stesso programma. In caso contrario, viene generato un errore del linker.Se un singolo modulo nel programma contiene entrambe
dllimport
le dichiarazioni edllexport
per la stessa funzione o oggetto, l'attributodllexport
ha la precedenza sull'attributodllimport
. Viene tuttavia generato un avviso del compilatore. Ad esempio:__declspec( dllimport ) int i; __declspec( dllexport ) int i; // Warning; inconsistent; // dllexport takes precedence.
In C++, è possibile inizializzare un puntatore dati locale dichiarato a livello globale o statico o con l'indirizzo di un oggetto dati dichiarato con l'attributo
dllimport
, che genera un errore in C. Inoltre, è possibile inizializzare un puntatore a funzione locale statico con l'indirizzo di una funzione dichiarata con l'attributodllimport
. In C tale assegnazione imposta il puntatore sull'indirizzo del thunk di importazione della DLL (uno stub di codice che trasferisce il controllo alla funzione) anziché sull'indirizzo della funzione. In C++ imposta il puntatore sull'indirizzo della funzione. Ad esempio:__declspec( dllimport ) void func1( void ); __declspec( dllimport ) int i; int *pi = &i; // Error in C static void ( *pf )( void ) = &func1; // Address of thunk in C, // function in C++ void func2() { static int *pi = &i; // Error in C static void ( *pf )( void ) = &func1; // Address of thunk in C, // function in C++ }
Tuttavia, poiché un programma che include l'attributo
dllexport
nella dichiarazione di un oggetto deve fornire la definizione per tale oggetto in un punto del programma, è possibile inizializzare un puntatore a funzione statico globale o locale con l'indirizzo di unadllexport
funzione. Analogamente, è possibile inizializzare un puntatore a dati statico globale o locale con l'indirizzo di un oggetto datidllexport
. Ad esempio, il seguente codice non genera errori in C o in C++:__declspec( dllexport ) void func1( void ); __declspec( dllexport ) int i; int *pi = &i; // Okay static void ( *pf )( void ) = &func1; // Okay void func2() { static int *pi = &i; // Okay static void ( *pf )( void ) = &func1; // Okay }
Se si applica
dllexport
a una classe regolare con una classe base non contrassegnata comedllexport
, il compilatore genererà C4275.Il compilatore genera lo stesso avviso se la classe base è una specializzazione di un modello di classe. Per risolvere questo problema, contrassegnare la classe base con
dllexport
. Il problema relativo a una specializzazione di un modello di classe è la posizione in cui inserire .__declspec(dllexport)
Non è consentito contrassegnare il modello di classe. Creare invece un'istanza esplicita del modello di classe e contrassegnare questa istanza esplicita condllexport
. Ad esempio:template class __declspec(dllexport) B<int>; class __declspec(dllexport) D : public B<int> { // ...
Questa soluzione alternativa non riesce se un argomento del modello è la classe di derivazione. Ad esempio:
class __declspec(dllexport) D : public B<D> { // ...
Poiché si tratta di un modello comune con i modelli, il compilatore ha modificato la semantica di
dllexport
quando viene applicata a una classe con una o più classi base e quando una o più classi di base è una specializzazione di un modello di classe. In questo caso, il compilatore si applicadllexport
in modo implicito alle specializzazioni dei modelli di classe. È possibile eseguire le operazioni seguenti e non ricevere un avviso:class __declspec(dllexport) D : public B<D> { // ...
Fine sezione specifica Microsoft
Vedi anche
Commenti e suggerimenti
https://aka.ms/ContentUserFeedback.
Presto disponibile: Nel corso del 2024 verranno gradualmente disattivati i problemi di GitHub come meccanismo di feedback per il contenuto e ciò verrà sostituito con un nuovo sistema di feedback. Per altre informazioni, vedereInvia e visualizza il feedback per