Importation à l'aide de fichiers DEF
Si vous choisissez d’utiliser __declspec(dllimport)
avec un fichier .def, vous devez modifier le fichier .def pour utiliser DATA à la place de CONSTANT pour réduire la probabilité que le codage incorrect provoque un problème :
// project.def
LIBRARY project
EXPORTS
ulDataInDll DATA
Le tableau suivant montre pourquoi.
Mot clé | Émet dans la bibliothèque d’importation | Exports |
---|---|---|
CONSTANT |
_imp_ulDataInDll , _ulDataInDll |
_ulDataInDll |
DATA |
_imp_ulDataInDll |
_ulDataInDll |
L’utilisation __declspec(dllimport)
et CONSTANT répertorie à la fois la imp
version et le nom non décodé dans la bibliothèque d’importation DLL .lib créée pour autoriser la liaison explicite. L’utilisation __declspec(dllimport)
et les listes DATA ne répertorient que la imp
version du nom.
Si vous utilisez CONSTANT, l’une des constructions de code suivantes peut être utilisée pour accéder ulDataInDll
à :
__declspec(dllimport) ULONG ulDataInDll; /*prototype*/
if (ulDataInDll == 0L) /*sample code fragment*/
-ou-
ULONG *ulDataInDll; /*prototype*/
if (*ulDataInDll == 0L) /*sample code fragment*/
Toutefois, si vous utilisez DATA dans votre fichier .def, seul le code compilé avec la définition suivante peut accéder à la variable ulDataInDll
:
__declspec(dllimport) ULONG ulDataInDll;
if (ulDataInDll == 0L) /*sample code fragment*/
L’utilisation de CONSTANT est plus risquée, car si vous oubliez d’utiliser le niveau supplémentaire d’indirection, vous pouvez potentiellement accéder au pointeur de la table d’adresses d’importation vers la variable, et non la variable elle-même. Ce type de problème peut souvent se manifester comme une violation d’accès, car la table d’adresses d’importation est actuellement effectuée en lecture seule par le compilateur et l’éditeur de liens.
L’éditeur de liens MSVC actuel émet un avertissement s’il voit CONSTANT dans le fichier .def pour prendre en compte ce cas. La seule raison réelle d’utiliser CONSTANT est si vous ne pouvez pas recompiler un fichier objet où le fichier d’en-tête n’a pas été listé __declspec(dllimport)
sur le prototype.