DLL_基础2

原创 2007年09月12日 01:57:00
 

什么是 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 属性。

返回页首

DLL 问题和故障排除工具

初始化问题

在 DLL 初始化过程中,您可能会遇到下列一个或多个问题:
如果计划服务的服务帐户密码与域用户管理器帐户的密码不同,则您在计划服务时可能会收到以下初始化错误信息:
Initialization of dynamic link library c:/winnt/system32/KERNEL32.dll failed.Process is terminating abnormally
有关其他信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
250265 使用 Cmd.exe 运行 AT 计划命令时出现 Kernel32.dll 动态链接库初始化错误
如果不断加载和卸载 Crypt32.dll,则在加载 Crypt32.dll 时将分配传输层安全性 (TLS),但在卸载 Crypt32.dll 时却不释放它。此行为可能导致一般性保护错误 (GPF) 错误,并且您可能会收到以下错误信息:
Initialization of the dynamic link library C:/WINNT40/System32/CRYPT32.dll failed.The process is terminating abnormally.
有关其他信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
212825 SMS:一般性保护错误:Initialization of CRYPT32.DLL Failed(CRYPT32.DLL 初始化失败)
如果您将计算机升级到 McAfee VirusScan 6.0,则可能会在启动 Outlook 2000 后的三分钟内收到以下错误信息:
Outlook.exe. DLL initialization failed.Initialization of c:/winnt/system32/compstui.dll. Process is terminating abnormally.
有关其他信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
310413 OL2000:升级到 McAfee VirusScan 6.0 后 Outlook 2000 发生 DLL 初始化错误
如果您将 Windows NT Mail 或 MSMail32.exe 设置为按计划启动,计划服务可能被记录为系统以外的其他内容,而且您可能会收到以下错误信息:
Initialization of the Dynamic Link Library OLECLI32.dll failed Abnormally
有关其他信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
133476 Windows NT 邮件错误信息:Initialization of the Dynamic Link...(动态链接的初始化...)
如果远程访问服务 (RAS) 文件或调制解调器文件丢失或损坏,并且您试图打开控制面板,则可能会收到以下错误信息:
Explorer.exe - DLL Initialization Failed Initialization of the dynamic link library E:/WINNT/System32/RASSCRPT.dll failed.The process is terminating abnormally.
有关其他信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
184443 错误信息:Explorer.exe - DLL Initialization Failed...(Explorer.exe — DLL 初始化失败...)
如果系统内存不足,无法为正在启动的服务创建新的桌面堆栈,您可能会收到以下错误信息:
ServiceName - DLL initialization failure Initialization of the dynamic link library c:/windows/system32/user32.dll failed.The process is terminating abnormally.
有关其他信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
142676 解决 User32.dll 初始化失败错误
返回页首

依赖性问题

如果您没有等到所有系统服务开始运行就启动您的服务,可能会遇到依赖性问题。例如,服务依赖于其他服务或驱动程序。这些服务或驱动程序又转而依赖于另外一些服务或驱动程序。更确切地说,RasApi32.dll 隐式依赖于 RAS 服务。使用 Rasapi32.dll 上的 LoadLibrary 的一个 Windows NT 服务使该服务依赖于 RAS 服务。

在您对项目进行更改时,定期通过“项目”菜单扫描所有依赖项以确保依赖性列表的准确性。如果您在执行依赖性扫描之前未保存对项目中文件所做的更改,新的依赖项不会显示在列表中。

返回页首

性能问题

如果加载应用程序的同时加载隐式链接到该应用程序的 DLL,则会出现性能问题。例如,当运行 Windows 2000 的计算机在内存中加载 Winmm.dll 文件时,可能会出现延迟。此延迟可能会在不同的时间发生,具体取决于 Winmm.dll 文件是如何加载的:
如果程序使用导入库来加载 Winmm.dll 文件,则 Winmm.dll 在程序启动时加载。在这种情况下,可能会在启动程序时出现延迟。因此,如果使用批处理文件多次启动此程序,性能会显著下降。
如果程序使用 LoadLibrary 加载 Winmm.dll 文件,则 Winmm.dll 仅在程序需要时才加载。例如,如果在您打开菜单时 Explorer.exe 播放声音,则在第一次播放声音时加载 Winmm.dll 文件。在这种情况下,可能会在程序加载 Winmm.dll 文件时出现延迟。
要提高性能,请在加载时使用优化技巧。另外,可将 DLL 分为两个 DLL:
将调用应用程序在加载后立刻需要的所有函数放入一个 DLL,然后将该调用应用程序隐式链接到此 DLL。
将调用应用程序不立即需要的函数放入另一个 DLL,然后将该应用程序显式链接到此 DLL。
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

vs环境下C++dll生成和使用(基础篇)

动态库和静态库:**动态库:全名动态链接库,用于将你的函数封装,让别人只能调用,不能看你的实现代码。由引入库和dll组成:引入库包含导出的函数和变量名,dll包含实际的函数和数据,运行时加载访问dll...

Visual Studio 2010 中的DLL基础知识

对于DLL的链接,新手还是会有很大麻烦,这里把一些基础知识列出来,本文所有内容源于MSDN文档 从DLL中导出函数 DLL和一般可执行程序的区别:   主要是DLL只能在系统中运行一个实例并且它...

windows DLL编程基础

DLL概述DLL是Dynamic Link Library的缩写,即动态链接库。一般来讲DLL是一种磁盘文件,以.dll结尾的文件,但以.drv,.SYS,甚至.exe为扩展名的文件也可以是DLL。D...

MFC基础知识(九)——几种创建DLL动态库的方法

本文主要介绍:用VS创建DLL动态库的几种方法:                               1. 创建DLL工程+MFC头文件 &#...

Windows的DLL基础

Windows中三个最重要的DLL分别是: # Kernel32.dll,包含的函数用来管理内存、进程以及线程; # User32.dll,包含的函数用来执行与用户界面相关的任务; # ...

每次使用都要去Google的基础知识--.lib与.dll

应该很多人对lib和dll理解的不够深刻,今晚就八一八。主要参考链接: https://www.cppfans.org/1394.html http://www.codeproject.com/A...

Windows核心编程(十八)DLL基础

DLL全称dynamic linking library。即动态链接库。广泛应用与windows及其他系统中。   windows中所有API都包含在DLL中。三个最重要的DLL是Kernel3...

第十九章:DLL基础

1.                  我们必须理解一个地址空间是由一个可执行模块和多个DLL模块构成的.当一个模块提供...

c++基础4:c++工程的动态链接库dll的导出使用方法

c++工程生成的动态链接库如果想给别的工程(包括.net工程,MFC工程等)使用,就必须遵守一些规则进行编译导出动态库(注意:这里是指两个不同的工程调用,如果同一个工程里的函数就不用这么做了): 下...

动态链接库DLL基础编程

(由于原文部分代码在VC下存在书写方式及编译问题,所以进行了修正) 本文对通用的DLL技术做了一个总结,并提供了源代码打包下载,下载地址为: http://www.blogjava.net/F...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)