如果你是程序员,你会知道你需要用函数库或者类库来编程。也就是说,通常库是程序的有机组成部分,可以静态链接(。lib,在使用之前。lib,参考头文件。h对应于程序源代码中的lib并在编译时直接添加到源文件中)或者动态链接(DLL,程序运行时加载)作为程序的一部分。
在Windows中,许多应用程序并不是一个完整的可执行文件,它们被分割成一些相对独立的动态链接库,即DLL文件,放置于系统中。当我们执行某一个程序时,相应的DLL文件就会被调用。一个应用程序可使用多个DLL文件,一个DLL文件也可能被不同的应用程序使用,这样的DLL文件被称为共享DLL文件。如在 Windows操作系统中,每个程序都可以使用该 DLL 中包含的功能来实现“打开”对话框。这有助于促进代码重用和内存的有效使用。通过使用 DLL,程序可以实现模块化,由相对独立的组件组成。MS把所有的API函数是放在几个大的*.LIB中,另外还提供一对应的几个*.inc,实际上它如同*.h头文件,起到声明API函数的目的。DLL是动态链接库的缩写,意思是动态链接库。在Windows中,很多应用程序都不是一个完整的可执行文件。分为一些相对独立的动态链接库,也就是DLL文件,放在系统中。当我们执行某个程序时,会调用对应的DLL文件。一个应用程序可以有多个动态链接库文件,一个动态链接库文件可以由几个应用程序共享。这样的DLL文件叫做共享DLL文件。一般DLL文件存储在C:WindowsSystem目录下。
DLL文件存储各种程序的函数(子过程)。当一个程序需要调用一个函数时,需要先加载DLL,然后获取函数的地址,最后调用。使用DLL文件的好处是程序在运行开始时不需要加载所有代码,只在程序需要的时候从DLL中取出一个函数。此外,使用动态链接库文件也可以减少程序的大小。
Windows系统平台上,你可以将独立的程序模块创建为较小的DLL(Dynamic Linkable Library)文件,并可对它们单独编译和测试。在运行时,只有当EXE程序确实要调用这些DLL模块的情况下,系统才会将它们装载到内存空间中。这种方式不仅减少了EXE文件的大小和对内存空间的需求,而且使这些DLL模块可以同时被多个应用程序使用。Microsoft Windows自己就将一些主要的系统功能以DLL模块的形式实现。例如IE中的一些基本功能就是由DLL文件实现的,它可以被其它应用程序调用和集成。一般来说,DLL是一种磁盘文件(通常带有DLL扩展名,是标准win32可执行文件-“PE”格式),它由全局数据、服务函数和资源组成,在运行时被系统加载到进程的虚拟空间中,成为调用进程的一部分,进程中所有线程都可以调用其中的函数。如果与其它DLL之间没有冲突,该文件通常映射到进程虚拟空间的同一地址上。DLL模块中包含各种导出函数,用于向外界提供服务。Windows在加载DLL模块时将进程函数调用与DLL文件的导出函数相匹配。在系统的组策略和注册表中,我们可以修改一些键值来优化我们的系统,加强操作系统的安全性。但是对于限制下载、禁止删除文件等功能,我们无法完成这些操作,只能通过修改系统DLL文件来完成。目前通过修改系统的DLL文件,可以实现禁止删除文件、禁止IE下载、禁止IE另存为、禁止文件打开方式等功能。
2 为什么要用DLL为什么把DLL封装成函数,这可能是系统中广泛使用DLL的原因?
(1)扩展应用
因为DLL可以被应用程序动态加载到内存中。所以应用可以在需要的时候把DLL加载到内存中,使得程序的可维护性非常高。比如QQ的视频功能需要升级,负责编写QQ的程序员不需要重写QQ的所有代码,只需要重写视频功能相关的DLL文件即可。
②方便程序员之间的合作
这与最终用户关系不大,仅供理解。大家都知道编程工具很多,比如VB,VC,Delphi等。如果几个人合作写一个大程序,那么可能有人用VB,有人用VC,每个人用的编程语言都不一样。应该在哪个编译器中编译?就像一群来自不同国家的人一起写一篇文章。如果他们使用不同的语言,写出来的文章怎么会在一起?有了DLL,VC程序员就可以写一个DLL,然后VB程序员就可以在程序中调用,不用担心如何把它们编译成单个的EXE。
③节省内存
如果多个应用程序调用同一个DLL,DLL文件不会重复加载到内存中,但是加载到内存中的同一个DLL会被这些应用程序共享。就像在办公室里,每个员工很少配备饮水机,而是在公共场所放置饮水机。所有需要用水的员工都可以共用这个饮水机,降低了成本,节约了空。
④共享节目资源
包括刚才提到的通用文件对话框,DLL文件提供了应用之间共享资源的可能性。资源可以是程序对话框、字符串、图标或声音文件。
⑤解决应用本地化问题
下载一个程序的中文包,打开中文描述后,经常可以看到程序的原始DLL被下载包中的DLL文件覆盖,中文版完成。这些程序是与执行代码和应用程序接口分开编写的,所以Chinesizer只需要将程序接口相关的DLL进行汉化和发布即可。
3 隐式链接和显式链接DLL文件中应用导入函数和导出函数的链接方式有两种:隐式链接和显式链接。
加载时动态链接意味着应用程序中不需要指明DLL文件的实际存储路径,程序员也不需要关心DLL文件的实际加载(编译器自动完成地址分配)。通过使用隐式链接方法,当程序员创建一个DLL文件时,链接器会自动生成一个相应的LIB导入文件。该文件包含每个DLL导出函数的符号名和可选标识号,但不包含实际代码。LIB文件被编译到应用程序项目中,作为DLL的替代。程序员通过静态链接编译生成应用程序时,应用程序中的调用函数与LIB文件中导出的符号相匹配,这些符号或标识号进入生成的EXE文件。LIB文件还包含相应的DLL文件名(但不是完整的路径名),由链接器存储在EXE文件中。当应用程序在运行过程中需要加载一个DLL文件时,Windows根据这个信息发现并加载DLL,然后通过符号名或标识号动态链接DLL函数。我们使用的大部分系统dll都是这样链接的。如果找不到所需的Dll,将会给出一条错误消息,说明该Dll丢失。
运行时动态链接则相反。用户程序没有指出编译时需要哪些dll,而是在运行后调用Win32的LoadLibary()函数加载dll。如果没有找到Dll,这个函数将返回一个错误。在用LoadLibary()函数加载了Dll之后,应用程序还需要使用GetProcAdress()函数来获取Dll输出函数的地址。显式链接适用于集成开发语言。有了显式链接,程序员不再使用导入文件,而是直接调用Win32的LoadLibary()函数,并将DLL的路径指定为参数。还有一点需要注意的是,knowdlls确保了当通过LoadLibary()加载系统dll时,它只从特定的系统目录加载,以防止加载错误。加载时会检查注册表下是否有相同的注册表项名称。
应用程序如何找到动态链接库文件
如果应用程序使用LoadLibrary显式链接,那么可以在这个函数的参数中指定DLL文件的完整路径。如果您没有指定路径或建立隐式链接,窗口将按照以下搜索顺序定位该动态链接库:
I 包含EXE文件的目录,II 进程的当前工作目录,III Windows系统目录,IV Windows目录,V 列在Path环境变量中的一系列目录。在Windows上,有决定dll搜索顺序的注册表项:hklmsystemcurrentcontrolsetsessionmanager safedlsearchmode。该值在windows 7 server 2003 XP SP2中为1,在XP 2000 sp4中为0。
1,搜索顺序是:1。可执行文件所在的目录,2。系统目录4.windowssystem32,3。16位系统目录,4。windows目录,和5。当前进程目录。6.环境变量PATH中的目录。
当值为0时,搜索顺序为:1。可执行文件所在的目录,2。当前进程目录。3.系统目录窗口系统32,4。16位系统目录,5.windows目录,6。环境变量PATH中的目录。
4 DLL的加载与连接Windows DLL加载(ntdll.dll除外)和连接是通过ntdll.dll的一个函数LdrInitializeThunk实现的。首先解释函数名LdrInitializeThunk()。“Ldr”显然是“Loader”的缩写。而“Thunk”的意思是“翻译”、“转换”,或者是起到“桥梁”作用的东西。这个词在一般字典里是找不到的,但在微软资料和文档中却是常用词。这个术语起源于编译技术,意思是一小段旨在获取地址的代码。它最初用于函数调用中“形式参数”和“实际参数”的组合。后来这个术语有了很多新的特殊含义和用途,但是DLL的动态连接本质上类似于调用函数时的“形式与现实的结合”。
一个DLL文件包含一个导出函数表。这些派生函数通过它们的符号名和称为标识号的整数与外界联系在一起。函数表还包含DLL中函数的地址。当应用程序加载一个DLL模块时,它不知道调用函数的实际地址,但它知道函数的符号名和标识号。动态链接过程在加载DLL模块时动态建立函数调用和函数地址的对应关系表。如果重新编译并重建DLL文件,除非更改导出函数的符号名和参数序列,否则不需要修改应用程序。
5 DLL注册及为什么需要注册?许多系统故障是由丢失、损坏或未注册的动态链接库文件引起的。例如,如果Windows XP的压缩文件夹功能失败,很可能是系统目录中的fldr.dll没有注册。对此类故障的大多数解决方案是下载相应的动态链接库并运行以下命令:
%1在(%windir%system32*。regsvr32.exe/s % 1
很多人不明白为什么。是不是所有的dll都可以做到这一点?
其实系统里有两种dll,一种不用注册就可以用,一种注册后才能用。就像员工名单上记录的临时工和长期合同工的区别一样。怎么才能区分这两个dll?方法很简单。可以用一个工具(比如Dependency Walker)打开这个DLL,看看函数输出表。如果它包含以下两个函数(前者是注册的DLL,后者是未注册的DLL),那么它必须是需要注册的DLL才能使用。
DllRegisterServerDllUnregisterServerregsvr32命令实际上是在DLL中调用这两个函数(“regsvr32 /u DLL文件名”调用DllUnregisterServer unregister函数)。
注册和不注册,。dll文件位于system32下。不同的是,如果注册的话,注册表中会有相应的信息,同时会加载到dll缓存中。如果没有注册信息和缓存,就无法使用(操作系统的一些核心功能会在你启动的时候加载到内存中,在后台开始运行,所以程序、数据、模块都需要进入内存才能访问。)。
文件注册前后没有变化,只有相应的信息通过命令添加到注册表中。
注册文件的命令行是regsrv32
regsrv 32 xxx.dll
reg SRV 32 xxx.dll/u
regsvr 32[/u][/s][/n][/I[:cmd line]]dllname
参数描述:
/u-注销服务器
/s-无声;不显示消息框
/I-调用DllInstall并向其传递可选的[cmd line];与/u一起使用时卸载dll。
/n-不要调用DllRegisterServer;此选项必须与/i一起使用。
-结束-
1.《dll文件 Windows DLL基本原理及为何需要注册》援引自互联网,旨在传递更多网络信息知识,仅代表作者本人观点,与本网站无关,侵删请联系页脚下方联系方式。
2.《dll文件 Windows DLL基本原理及为何需要注册》仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证。
3.文章转载时请保留本站内容来源地址,https://www.lu-xu.com/junshi/1222454.html