什么是 DLL?

动态链接库 (DLL) 是包含函数和数据的模块的集合。程序文件(如 .exe 文件或 .dll 文件)在运行时加载这些模块(亦即所需的模块映射到调用进程的地址空间)。下面两类函数定义了 DLL: • 导出函数:这些函数由其他模块调用。
• 内部函数:这些函数仅从定义它们的 DLL 中调用。
DLL 还导出数据。不过,这些数据由相应的函数使用。
动态链接和静态链接
动态链接包括系统在加载或运行时查找导出的 DLL 函数的代码所需的信息。

在静态链接中,链接器将库函数的代码复制到调用 DLL 的每个模块。

可以通过下列方式调用 DLL 中的函数: • 加载时动态链接:调用方模块执行显式调用以导出 DLL 函数。为 DLL 创建导入库,然后将 DLL 链接到应用程序。在加载应用程序时,导入库提供加载 DLL 和查找导出的 DLL 函数所需的信息。
• 运行时动态链接:在运行时加载 DLL 时,调用方模块使用 LoadLibrary 函数或 LoadLibraryEx 函数。调用方模块调用 GetProcAddress 函数以获取导出的 DLL 函数的地址。
在链接时,Windows 搜索预安装的一组 DLL,例如性能库 (Kernel32.dll) 和安全库 (User32.dll)。然后,Windows 按以下顺序搜索 DLL: 1. 当前进程的可执行程序所在的目录。
2. 当前目录。
3. Windows 系统目录。(GetSystemDirectory 函数获取 Windows 系统目录的路径。)
4. Windows 目录。(GetWindowsDirectory 函数获取 Windows 目录的路径。)
5. PATH 环境变量中列出的目录。

注意:LIBPATH 环境变量不用于搜索。

DLL 和静态库
• DLL 可节省内存并减少交换。 通过在内存中共享 DLL 的单个副本,多个进程可以同时使用一个 DLL。相比之下,对于使用静态链接库构建的每一个应用程序,Windows 都要在内存中为其加载库代码的一个副本。
• DLL 可节省磁盘空间。 多个应用程序可以共享磁盘上的一个 DLL 副本。相比之下,使用静态链接库构建的每一个应用程序都需要让链接到程序文件映像的库代码作为一个单独的专用副本。
• DLL 可节省时间。 更改 DLL 中的函数时,只要函数的参数和返回值不变,就不必重新编译或重新链接使用这些函数的应用程序。但是,如果您使用静态链接的对象代码,则在更改函数后必须重新链接应用程序。

DLL 可以共享函数。 在 Win32 中,DLL 可以共享函数。默认情况下,数据对于每个进程来说是独立的。但是,静态库包含针对每一个进程的单独的数据副本和函数。

DLL 入口点
DLL 有一个特殊的入口点(DllMain 函数),它在附加和分离进程和线程时运行。此行为允许根据需要创建和销毁数据结构。文件扩展名为 .ocx、.cpl 和 .drv 的文件类型也是 DLL,尽管文件扩展名已改变。在 Windows 2.x 和 Windows 3.x 中,每个 DLL 都只有一个数据段实例,而不管有多少应用程序。在 Windows 32 中,可以将 DLL 标记为共享以导致相同的行为。但是,每个进程的默认设置是拥有 DLL 数据的专用副本。
您可以通过创建 DLL 实现以下目的: • 将程序划分为可按需加载的单独模块。
• 存储特定于语言或特定于区域的资源。
• 使您自己的应用程序能够使用核心代码库。
• 生成进程内 COM 对象或 ActiveX 控件 (OCX)。
• 将 OLE 对象用作进程内 DLL。这一用法可改进 OLE 链接的性能。
• 使用控制面板扩展或使用某些类型的驱动程序。
要生成 DLL,请使用 DllMain 函数(而不是程序文件)替换 WinMain 函数。

要在 Win16 中导出函数,请将 FAR EXPORT 添加到所有导出的 DLL 函数(在 Win32 中不要求这样做)。许多 32 位编译器提供了函数声明符,例如 __declspec(dllexport) 和 __declspec(dllimport)。这些函数声明符出现在函数声明之前以代替调用。不过,定义必须仅指定 dllexport 属性。

posted on 2006-05-30 10:02  爱你一万年123  阅读(1061)  评论(0编辑  收藏  举报

导航