Importando usando arquivos DEF
Se você optar por usar __declspec(dllimport)
junto com um arquivo .def, deverá alterar o arquivo .def para usar DATA no lugar de CONSTANT para reduzir a probabilidade de codificação incorreta causar um problema:
// project.def
LIBRARY project
EXPORTS
ulDataInDll DATA
A tabela a seguir mostra por quê.
Palavra-chave | Emite na biblioteca de importação | Exportações |
---|---|---|
CONSTANT |
_imp_ulDataInDll , _ulDataInDll |
_ulDataInDll |
DATA |
_imp_ulDataInDll |
_ulDataInDll |
Usar __declspec(dllimport)
e CONSTANT listará a versão imp
e o nome não decorado na biblioteca de importação .lib DLL criada para permitir a vinculação explícita. Usar __declspec(dllimport)
e DATA listarão apenas a versão imp
do nome.
Se você usar CONSTANT, qualquer uma das seguintes construções de código poderá ser usada para acessar ulDataInDll
:
__declspec(dllimport) ULONG ulDataInDll; /*prototype*/
if (ulDataInDll == 0L) /*sample code fragment*/
-ou-
ULONG *ulDataInDll; /*prototype*/
if (*ulDataInDll == 0L) /*sample code fragment*/
No entanto, se você usar DATA no arquivo .def, somente o código compilado com a seguinte definição poderá acessar a variável ulDataInDll
:
__declspec(dllimport) ULONG ulDataInDll;
if (ulDataInDll == 0L) /*sample code fragment*/
Usar CONSTANT é mais arriscado porque, se você esquecer de usar o nível adicional de indireção, poderá acessar o ponteiro da tabela de endereços de importação para a variável — não a própria variável. Esse tipo de problema geralmente pode se manifestar como uma violação de acesso porque a tabela de endereços de importação é atualmente somente leitura pelo compilador e vinculador.
O vinculador do MSVC atual emitirá um aviso se verificar CONSTANT no arquivo .def para considerar esse caso. A única razão real para usar CONSTANT é se não for possível recompilar algum arquivo de objeto onde o arquivo de cabeçalho não listou __declspec(dllimport)
no protótipo.