导入和导出
可以使用两种方法将公共符号导入到应用程序中或从 DLL 导出函数:
生成 DLL 时使用模块定义 (.def) 文件
在主应用程序的函数定义中使用关键字 __declspec(dllimport) 或 __declspec(dllexport)
使用 .def 文件
模块定义 (.def) 文件是包含一个或多个描述 DLL 各种特性的 Module 语句的文本文件。 如果不使用 __declspec(dllimport) 或 __declspec(dllexport) 导出 DLL 函数,则 DLL 需要 .def 文件。
可以使用 .def 文件导入到应用程序中或从 DLL 导出。
使用 __declspec
Visual C++ 用 __declspec(dllimport) 和 __declspec(dllexport) 取代以前在 16 位版的 Visual C++ 中使用的 __export 关键字。
不使用 __declspec(dllimport) 也能正确编译代码,但使用它可以使编译器生成更好的代码。 编译器之所以能够生成更好的代码,是因为它可以确定函数是否存在于 DLL 中,这使得编译器可以生成跳过间接寻址级别的代码,而这些代码通常会出现在跨 DLL 边界的函数调用中。 但是,必须使用 __declspec(dllimport) 才能导入 DLL 中使用的变量。
如果有正确的 .def 文件 EXPORTS 节,则不需要 __declspec(dllexport)。 添加 __declspec(dllexport) 是为了提供不使用 .def 文件从 .exe 或 .dll 文件导出函数的简单方法。
Win32 可移植可执行文件格式旨在最小化为修改导入而必须访问的页数。 为此,它将所有程序的所有导入地址都放在一个称为“导入地址表”的位置。 这使得加载程序在访问这些导入时可以只修改一两页。