Importazione tramite i file DEF
Se si decide di utilizzare __declspec(dllimport) con un file def, occorre modificare quest'ultimo in modo da utilizzare DATA anziché CONSTANT allo scopo di ridurre la probabilità che si verifichi un problema a causa del codice errato:
// project.def
LIBRARY project
EXPORTS
ulDataInDll DATA
Nella tabella riportata di seguito sono illustrati i motivi di questa scelta:
Parola chiave |
Genera nella libreria di importazione |
Esporta |
---|---|---|
CONSTANT |
_imp_ulDataInDll_ulDataInDll |
_ulDataInDll |
DATA |
_imp_ulDataInDll |
_ulDataInDll |
L'utilizzo di __declspec(dllimport) e di CONSTANT consente di elencare sia la versione imp che il nome non decorato nella libreria di importazione della DLL (lib) creata per consentire il collegamento esplicito. Se si utilizza __declspec(dllimport) e DATA viene elencata solo la versione imp del nome.
Se si utilizza CONSTANT, è possibile utilizzare uno dei seguenti costrutti di codice per accedere a ulDataInDll:
__declspec(dllimport) ULONG ulDataInDll; /*prototype*/
if (ulDataInDll == 0L) /*sample code fragment*/
- oppure -
ULONG *ulDataInDll; /*prototype*/
if (*ulDataInDll == 0L) /*sample code fragment*/
Se tuttavia si utilizza DATA nel file def, soltanto il codice compilato con la seguente definizione può accedere alla variabile ulDataInDll:
__declspec(dllimport) ULONG ulDataInDll;
if (ulDataInDll == 0L) /*sample code fragment*/
L'uso di CONSTANT è più rischioso perché, se non si utilizza il livello aggiuntivo di riferimento indiretto, è possibile che si acceda al puntatore alla variabile nella tabella di indirizzi di importazione e non alla variabile vera e propria. Questo tipo di problema può manifestarsi spesso come violazione di accesso poiché la tabella IAT è attualmente impostata in sola lettura dal compilatore e dal linker.
Per segnalare questa situazione, il linker corrente di Visual C++ invia un messaggio di avviso se individua CONSTANT nel file def. L'unico motivo valido per utilizzare CONSTANT è dato dall'impossibilità di ricompilare un file oggetto in cui il file di intestazione non elenca __declspec(dllimport) nel prototipo.