Importazione tramite i file DEF
Se si sceglie di usare __declspec(dllimport)
insieme a un file con estensione def, è necessario modificare il file con estensione def in modo da usare DATA al posto di CONSTANT per ridurre la probabilità che la codifica non corretta causi un problema:
// project.def
LIBRARY project
EXPORTS
ulDataInDll DATA
Nella tabella seguente viene illustrato il motivo.
Parola chiave | Genera nella libreria di importazione | Esportazioni |
---|---|---|
CONSTANT |
_imp_ulDataInDll , _ulDataInDll |
_ulDataInDll |
DATA |
_imp_ulDataInDll |
_ulDataInDll |
L'uso di __declspec(dllimport)
e CONSTANT elenca sia la imp
versione che il nome non dichiarato nella libreria di importazione DLL .lib creata per consentire il collegamento esplicito. L'uso di __declspec(dllimport)
e DATA elenca solo la imp
versione del nome.
Se si usa CONSTANT, è possibile usare uno dei costrutti di codice seguenti per accedere ulDataInDll
a :
__declspec(dllimport) ULONG ulDataInDll; /*prototype*/
if (ulDataInDll == 0L) /*sample code fragment*/
oppure
ULONG *ulDataInDll; /*prototype*/
if (*ulDataInDll == 0L) /*sample code fragment*/
Tuttavia, se si usa DATA nel file con estensione def, solo il codice compilato con la definizione seguente può accedere alla variabile ulDataInDll
:
__declspec(dllimport) ULONG ulDataInDll;
if (ulDataInDll == 0L) /*sample code fragment*/
L'uso di CONSTANT è più rischioso perché se si dimentica di usare il livello aggiuntivo di riferimento indiretto, è possibile accedere potenzialmente al puntatore della tabella degli indirizzi di importazione alla variabile, non alla variabile stessa. Questo tipo di problema può spesso manifestarsi come violazione di accesso perché la tabella degli indirizzi di importazione è attualmente resa di sola lettura dal compilatore e dal linker.
Il linker MSVC corrente genera un avviso se viene visualizzato CONSTANT nel file con estensione def per tenere conto di questo caso. L'unico motivo reale per usare CONSTANT è se non è possibile ricompilare un file oggetto in cui il file di intestazione non è stato elencato __declspec(dllimport)
nel prototipo.