使用 DEF 文件导入

如果选择将 __declspec(dllimport) 与 .def 文件一起使用,应将 .def 文件更改为使用 DATA(而不是 CONSTANT),以减少错误编码导致问题的可能性:

// project.def
LIBRARY project
EXPORTS
   ulDataInDll   DATA

下表说明了原因。

关键字 在导入库中发出 导出
CONSTANT _imp_ulDataInDll_ulDataInDll _ulDataInDll
DATA _imp_ulDataInDll _ulDataInDll

使用 __declspec(dllimport) 和 CONSTANT 会列出为允许显式链接而创建的 .lib DLL 导入库中的 imp 版本和未修饰名。 使用 __declspec(dllimport) 和 DATA 只会列出名称的 imp 版本。

如果使用 CONSTANT,则可以使用以下任一代码构造来访问 ulDataInDll

__declspec(dllimport) ULONG ulDataInDll; /*prototype*/
if (ulDataInDll == 0L)   /*sample code fragment*/

- 或者 -

ULONG *ulDataInDll;      /*prototype*/
if (*ulDataInDll == 0L)  /*sample code fragment*/

但如果使用 .def 文件中的 DATA,则只有使用下面的定义编译的代码才能访问变量 ulDataInDll

__declspec(dllimport) ULONG ulDataInDll;

if (ulDataInDll == 0L)   /*sample code fragment*/

使用 CONSTANT 的风险更大,因为如果忘记使用额外级别的间接寻找,则访问的有可能是指向变量的导入地址表的指针,而不是变量本身。 由于导入地址表当前被编译器和链接器设置成了只读,因此这类问题经常表现为访问冲突。

如果当前 MSVC 链接器发现 .def 文件中的 CONSTANT 是导致上述问题的原因,它将发出警告。 使用 CONSTANT 的唯一真正原因是,在头文件没有在原型上列出 __declspec(dllimport) 的情况下,无法重新编译某对象文件。

另请参阅

导入到应用程序中