深入学习Windows动态链接库

合集下载

动态链接库——精选推荐

动态链接库——精选推荐

动态链接库动态链接库--------------------------------------------------------------------------------动态链接库(也称为DLL)是Microsoft Windows最重要的组成要素之⼀。

⼤多数与Windows相关的磁盘⽂件如果不是程序模块,就是动态链接程序。

迄今为⽌,我们都是在开发Windows应⽤程序;现在是尝试编写动态链接库的时候了。

许多您已经学会的编写应⽤程序的规则同样适⽤于编写这些动态链接库模块,但也有⼀些重要的不同。

动态链接库的基本知识正如前⾯所看到的,Windows应⽤程序是⼀个可执⾏⽂件,它通常建⽴⼀个或⼏个窗⼝,并使⽤消息循环接收使⽤者输⼊。

通常,动态链接库并不能直接执⾏,也不接收消息。

它们是⼀些独⽴的⽂件,其中包含能被程序或其它DLL呼叫来完成⼀定作业的函数。

只有在其它模块呼叫动态链接库中的函数时,它才发挥作⽤。

所谓「动态链接」,是指Windows把⼀个模块中的函数呼叫连结到动态链接库模块中的实际函数上的程序。

在程序开发中,您将各种⽬标模块(.OBJ)、执⾏时期链接库(.LIB)⽂件,以及经常是已编译的资源(.RES)⽂件连结在⼀起,以便建⽴Windows的.EXE⽂件,这时的连结是「静态连结」。

动态链接与此不同,它发⽣在执⾏时期。

KERNEL32.DLL、USER32.DLL和GDI32.DLL、各种驱动程序⽂件如KEYBOARD.DRV、SYSTEM.DRV和MOUSE.DRV和视讯及打印机驱动程序都是动态链接库。

这些动态链接库能被所有Windows应⽤程序使⽤。

有些动态链接库(如字体⽂件等)被称为「纯资源」。

它们只包含数据(通常是资源的形式)⽽不包含程序代码。

由此可见,动态链接库的⽬的之⼀就是提供能被许多不同的应⽤程序所使⽤的函数和资源。

在⼀般的操作系统中,只有操作系统本⾝才包含其它应⽤程序能够呼叫来完成某⼀作业的例程。

动态链接库教程

动态链接库教程

动态链接库教程动态链接库(Dynamic Link Library,简称DLL)是一种可由多个程序共享的库文件,它包含了一组函数和数据,可以在程序运行时加载和调用。

DLL 文件可用于将一些通用的功能封装成函数,供多个程序调用,从而提高代码的复用性和开发效率。

本文将详细介绍动态链接库的概念、使用方法以及制作过程。

一、动态链接库的概念动态链接库是一种包含了函数和数据的库文件,它可以在程序运行时被加载和调用。

与静态链接库相比,动态链接库的优势在于节省内存空间和提高代码的复用性。

当多个程序需要使用同一个功能时,它们可以共享同一个DLL文件,避免了重复编写相同的代码。

二、动态链接库的使用方法在使用动态链接库之前,我们首先需要了解动态链接库的编译、加载和调用过程。

1.编译动态链接库在创建 DLL 文件时,我们需要按照一定的规范编写代码,并将其编译成 DLL 文件。

编译时,需要指定导出函数的修饰符(如 _stdcall、_cdecl等),以及导出函数的声明。

这些步骤可以在开发环境(如Visual Studio)中完成。

2.加载动态链接库在程序运行时,需要加载 DLL 文件。

我们可以通过调用LoadLibrary 函数来加载 DLL,该函数返回一个句柄,表示 DLL 的实例。

加载 DLL 文件后,我们可以通过该句柄获取 DLL 中导出函数的地址。

3.调用动态链接库在获取到DLL中导出函数的地址后,我们可以通过函数指针来调用DLL中的函数。

通过函数指针,程序可以跳转到DLL中执行指定的函数,从而完成相应的功能。

三、制作动态链接库下面以C++语言为例,简单介绍如何制作一个动态链接库。

1.创建DLL工程在 Visual Studio 中创建一个 DLL 项目,选择 DLL(动态链接库)作为项目类型。

在项目中添加需要导出的函数,并在头文件中进行声明。

2.编写导出函数在 DLL 项目中编写需要导出的函数,并在函数前添加修饰符(如_stdcall、_cdecl等)。

动态链接库的使用方法

动态链接库的使用方法

动态链接库的使用方法动态链接库(Dynamic Link Library,DLL)是Windows系统中一种常见的文件类型,用于存储可被程序在运行时动态加载的函数和数据。

它可以提供代码和资源的共享,使得程序的安装包更小,节省了系统资源。

使用动态链接库有以下几个优点:1.模块化:将程序代码和资源划分为独立的模块,便于开发和维护。

2.共享性:多个程序可以共享同一个动态链接库,减少重复的代码和数据的存储。

3.动态加载:可以在程序运行时动态地加载和卸载动态链接库,提高了程序的灵活性和可扩展性。

1.创建动态链接库:使用C/C++编程语言可以创建动态链接库。

首先,在开发环境中创建新的DLL项目,并选择动态链接库的类型。

在项目中添加需要的代码和资源,并编写相应的函数和数据接口。

将这些接口封装在一个头文件中,并在源文件中实现具体的功能。

最后,编译项目生成动态链接库文件(.dll 文件)。

2.导出函数和数据:在动态链接库中,明确指定哪些函数和数据需要被其他程序调用。

在函数和数据的声明前加上__declspec(dllexport)关键字即可。

例如:```C++__declspec(dllexport) int Add(int a, int b);```3.调用动态链接库:在其他程序中调用动态链接库中的函数和数据,需要先导入相应的函数和数据。

使用C/C++编程语言可以创建一个头文件,其中包含要导入的函数和数据的声明。

例如:```C++__declspec(dllimport) int Add(int a, int b);__declspec(dllimport) extern double PI;```然后,在使用这些函数和数据的源文件中包含这个头文件即可。

4.加载和卸载动态链接库:在程序运行时,需要动态地加载动态链接库,并在使用完之后卸载。

可以使用LoadLibrary函数来加载动态链接库,使用FreeLibrary函数来卸载动态链接库。

C基础语法梳理:Windows的动态链接库

C基础语法梳理:Windows的动态链接库

C基础语法梳理:Windows的动态链接库https:///is/RhWSw8D/?=windows核心编程Windows 应用程序入口函数GUI(Graphical User Interface)应用,链接器选项:/SUBSYSTEM:WINDOWSCUI(Console User Interface)应用,链接器选项:/SUBSYSTEM:CONSOLE_tWinMain 与 _tmain 函数声明Int WINAPI _tWinMain( HINSTANCE hInstanceExe, HINSTANCE, PTSTR pszCmdLine, int nCmdShow);int _tmain( int argc, TCHAR *argv[], TCHAR *envp[]);Windows 的动态链接库(Dynamic-Link Library)部分知识点来自《Windows 核心编程(第五版)》用处(1)扩展了应用程序的特性(2)简化了项目管理(3)有助于节省内存(4)促进了资源的共享(5)促进了本地化(6)有助于解决平台间的差异(7)可以用于特殊目的注意(1)创建 DLL,事实上是在创建可供一个可执行模块调用的函数(2)当一个模块提供一个内存分配函数(malloc、new)的时候,它必须同时提供另一个内存释放函数(free、delete)(3)在使用 C 和 C++ 混编的时候,要使用 extern 'C' 修饰符(4)一个 DLL 可以导出函数、变量(避免导出)、C++ 类(导出导入需要同编译器,否则避免导出)(5)DLL 模块:cpp 文件中的__declspec(dllexport) 写在include 头文件之前(6)调用DLL 的可执行模块:cpp 文件的__declspec(dllimport) 之前不应该定义 MYLIBAPI加载 Windows 程序的搜索顺序1、包含可执行文件的目录2、Windows 的系统目录,可以通过 GetSystemDirectory 得到3、16 位的系统目录,即 Windows 目录中的 System 子目录4、Windows 目录,可以通过 GetWindowsDirectory 得到5、进程的当前目录6、PATH 环境变量中所列出的目录DLL 入口函数DllMain 函数BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved){ switch(fdwReason) { case DLL_PROCESS_ATTACH: // 第一次将一个DLL映射到进程地址空间时调用 // The DLL is being mapped into the process' address space. break; case DLL_THREAD_ATTACH: // 当进程创建一个线程的时候,用于告诉DLL执行与线程相关的初始化(非主线程执行) // A thread is bing created. break; case DLL_THREAD_DETACH: // 系统调用 ExitThread 线程退出前,即将终止的线程通过告诉DLL执行与线程相关的清理 // A thread is exiting cleanly. break; case DLL_PROCESS_DETACH: // 将一个DLL从进程的地址空间时调用// The DLL is being unmapped from the process' address space. break; } return(TRUE); // Used only for DLL_PROCESS_ATTACH}载入卸载库LoadLibrary、LoadLibraryExA、LoadPackagedLibrary、FreeLibrary、FreeLibraryAndExitThread 函数声明// 载入库HMODULE WINAPI LoadLibrary( _In_ LPCTSTR lpFileName);HMODULE LoadLibraryExA( LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags);// 若要在通用Windows 平台(UWP)应用中加载Win32 DLL,需要调用LoadPackagedLibrary,而不是LoadLibrary 或LoadLibraryExHMODULE LoadPackagedLibrary( LPCWSTR lpwLibFileName, DWORD Reserved);// 卸载库BOOL WINAPI FreeLibrary( _In_ HMODULE hModule);// 卸载库和退出线程VOID WINAPI FreeLibraryAndExitThread( _In_ HMODULE hModule, _In_ DWORD dwExitCode);显示地链接到导出符号GetProcAddress 函数声明FARPROC GetProcAddress( HMODULE hInstDll, PCSTR pszSymbolName // 只能接受 ANSI 字符串,不能是 Unicode);DumpBin.exe 查看 DLL 信息在 VS 的开发人员命令提示符使用 DumpBin.exe 可查看 DLL 库的导出段(导出的变量、函数、类名的符号)、相对虚拟地址(RVA,relative virtual address)。

Windows应用程序与动态链接库2

Windows应用程序与动态链接库2

创建Dቤተ መጻሕፍቲ ባይዱL
① ② ③ ④ ⑤ 创建带有输出原型/结构/符号的头文件 创建实现输出函数/变量的C/C++源文件 编译器为每个C/C++源文件生成.obj文件 链接程序结合.obj模块以生成DLL 如果至上有一个函数/变量输出,则链接 程序同时也生成.lib文件
DLL的调用
隐式调用 隐式调用又称静态调用或装载时调用,对应于 DLL的静态载入。要在应用程序中隐式调用某 个动态链接库中的函数,一般要做以下两件事 情: (1)用extern子句声明要调用的过程或函数及 其所在的DLL文件名; (2)在应用程序中直接调用用extern子句声明 的过程
DLL函数的入口地址
BOOL WINAPI DllMain //函数名DllMain是区分大小写的 (HANDLE hinstDll, //包含了DLL的实例句柄 DWORD fdwReason, //系统调用该函数的原因 LPVOID lpReserved) //0表示显示链接,非0表示隐式
示例:编写一个简单的DLL模块并在 用户程序中进行调用
DLL特点
一个DLL在内存中只有一个实例,使之能高效 经济地使用内存,降低可共享代码的内存使用 量; DLL实现的代码封装性,使得程序简洁明晰, 提供给每个程序组一致的APIs让用户进行调用, 在用户程序运行时被载入; DLL的编制与具体的编程语言及编译器无关, 只要遵守DLL的开发规范和编程策略,并安排 正确的调用接口,不管用何种编程语言编制的 DLL都具有通用性。
静态链接和动态链接
(1)静态链接
传统的库函数是通过静态链接链到应用程序中的。 这些库函数可能来自编程语言提供的标准库,也可能 是由操作系统提供的API。 API

动态链接库基本概念

动态链接库基本概念

动态链接库基本概念在 Windows中存在⼀种叫做DLL(Dynamic Linkable Library动态链接库)的⽂件。

它可以提供⼀些应⽤程序可以导⼊的数据、函数和类。

DLL⽂件平时驻留在磁盘中,只有当运⾏的应⽤程序确实要调⽤这些DLL模块的情况下,系统才会将它们装载到内存空间中。

这种⽅式不仅可以减少了应⽤程序EXE⽂件的⼤⼩和对内存空间的需求,耐⽽且这些DLL模块可以同时被多个应⽤程序所共享,从⽽极⼤⽅便了应⽤程序的设计。

以前曾经⽤库函数实现了代码共享。

这样存在⼀些缺点:⼀个缺点是增加了应⽤程序的代码量,它会占⽤更多的磁盘空间,同时在程序运⾏时也会占⽤较⼤的内存空间,从⽽造成了系统资源的浪费;另⼀个缺点是,在编写⼤的EXE程序时,每次重建时都必须⾼速编译所有源代码。

⽽DLL⽂件有以下为众所欢迎的特点:• 它是动态链接的,即平时它驻留在本地在计算机的硬盘中,只有当某应⽤程序确实要调⽤这些DLL模块的情况下,系统才会将它们从磁盘上装载到内存空间中,因此它不会使应⽤程序的代码量加⼤。

• 它是公⽤的,即当它⼀旦被调⼊内存则在内存中它只有⼀份⽂件,⽽该⽂件可以被Windows应⽤程序所调⽤。

• 当已经没有应⽤程序再需要调⽤它时,它会⾃动卸载以释放所占⽤的内存。

• 它们扩展了应⽤程序的特性。

• 它们可以⽤许多种编程语⾔来编写。

• 它们简化了软件项⽬的管理。

• 它们有助于资源的共享。

• 它们有助于应⽤程序的本地化• 它们有助于解决平台差异。

• 它们可以⽤于⼀些特殊的⽬的。

动态链接库的组成DLL必须有⼀个类似main函数的⼊⼝函数。

还应该包含外部应⽤程序可以调⽤的函数对象和资源等。

1动态链接库的⼊⼝函数。

MFC AppWizard编写DLL时,在⼀般的情况下它都会给程序员提供⼀个默认的DLL⼊⼝函数。

BOOL WINAPI DllMain(HINSTANCE hinstDLL, // handle to DLL moduleDWORD fdwReason, // reason for calling functionLPVOID lpvReserved // reserved);第⼀个参数:是指向DLL本⾝的句柄;第⼆个参数:常被⽤来指明DLL被调⽤的原因;第三个参数:是系统所保留的参数;⼊⼝函数的主要作⽤就是在系统调⽤该DLL时,进⾏⼀些初始化⼯作。

动态链接库(dll)学习资料总结

动态链接库(dll)学习资料总结

1. 什么是lib文件,lib和dll的关系如何(1)lib是编译时需要的,dll是运行时需要的。

如果要完成源代码的编译,有lib就够了。

如果也使动态连接的程序运行起来,有dll就够了。

在开发和调试阶段,当然最好都有。

(2)一般的动态库程序有lib文件和dll文件。

lib文件是必须在编译期就连接到应用程序中的,而dll文件是运行期才会被调用的。

如果有dll文件,那么对应的lib文件一般是一些索引信息,具体的实现在dll文件中。

如果只有lib文件,那么这个lib文件是静态编译出来的,索引和实现都在其中。

静态编译的lib文件有好处:给用户安装时就不需要再挂动态库了。

但也有缺点,就是导致应用程序比较大,而且失去了动态库的灵活性,在版本升级时,同时要发布新的应用程序才行。

(3)在动态库的情况下,有两个文件,一个是引入库(.LIB)文件,一个是DLL文件,引入库文件包含被DLL导出的函数的名称和位置,DLL包含实际的函数和数据,应用程序使用LIB文件链接到所需要使用的DLL文件,DLL 库中的函数和数据并不复制到可执行文件中,因此在应用程序的可执行文件中,存放的不是被调用的函数代码,而是DLL中所要调用的函数的内存地址,这样当一个或多个应用程序运行时再把程序代码和被调用的函数代码链接起来,从而节省了内存资源。

从上面的说明可以看出,DLL和.LIB文件必须随应用程序一起发行,否则应用程序将会产生错误。

2、严重警告:(1) 用 extern "C" _declspec(dllexport) 只可以导出全局函数,不能导出类的成员函数(2) 使用extern "C" _declspec(dllexport)输出的函数可以被c语言调用,否则则不可(3) 注意标准调用约定的问题,输出与调用的函数约定应该一致,如当dll 模块的函数输出采用标准调用约定_stdcall,则调用程序的导入函数说明也要用标准约定(4) 用extern "C" _declspec(dllexport) 和 EXPOTRT导出的函数不改变函数名,可以给c++或c编写的exe调用.假如没有extern "C",导出的函数名将会改变,只能给c++编写的exe调用(5)在动态加载动态链接库函数时注意GetProcAddress(hInst,"add")中第二个参数是否为动态链接库导出的函数名,因为在生成动态库时可能会改变动态库导出函数的函数名,加上修饰符(6)dll初始化全局变量时,全局变量要放在共享数据断,并且初始化每一个变量,在StartHook函数里初始化其值,记得一进函数就初始化(7)调试时,编译器会自动查找其目录下(不含debug和release目录)的dll文件,所以dll文件应该放在主文件目录下,但生成的应用程序则只会在同一个目录下找dll(不需要lib文件),所以单纯的运行exe,不通过编译器,那就要把dll文件放在与exe相同的目录下(8)用#pragma comment(lib,"dllTest.lib")导入lib文件,不需要在设置里修改(9) dll里的指针变量不要用newDLL 调用方式DLL(动态连接库),可以分为动态调用于静态调用。

Windows编程技术13-动态链接库

Windows编程技术13-动态链接库
DLL成功加载,使用GetProcAddress()得到DLL中函数的指针。 GetProcAddress(HMODULE hModule,LPCSTR lpProcName);
释放DLL 使用完DLL后,应使用FreeLibrary()函数释放DLL。其函数原形为: BOOL FreeLibrary(HMODULE hModule); BOOL AfxFreeLibrary(HINSTANCE hInstLib );
显式加载 加载DLL 在动态加载DLL时,首先需要将DLL模块映射到进程的内存空间。该功 能可以由Windows API函数LoadLibrary()或MFC的全局函数 AfxLoadLibrary()实现。以下是LoadLibrary()函数原形。 HMODULE LoadLibrary(LPCTSTR lpFileName); HINSTANCE AfxLoadLibrary(LPCTSTR lpFileName); 取得函数指针

生成DLL
将以上程序进行编译链接,可以生成两个重要文件: “MyDll.lib”将在隐式链接时使用。 “MyDll.dll”即为生成的动态链接库,它包含函数代码,在程序执行 时链接使用。
5
创建标准MFC动态库

新建标准MFC动态库项目 添加函数

在“应用程序设置/应用程序类型”的选项中选MFC DLL类型,然后“ 完成”
Windows编程技术
动态链接库
1
概述
动态链接是在程序链接并最终生成可执行文件时,保留程 序到函数库的调用接口。当应用程序运行时,它需要通过其前 面的接口找到对应的函数库文件,当执行函数功能时,转到函 数库中的对应函数执行。 两种类型的DLL Win32 DLL MFC DLL 动态库的加载方式 隐式加载 显式加载。
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

在Windows 世界中,有无数块活动的大陆,它们都有一个共同的名字——动态链接库。

现在就让我们走进这些神奇的活动大陆,找出它们隐藏已久的秘密吧!初窥门径:Windows 的基石随便打开一个系统目录,一眼望去就能看到很多扩展名DLL 的文件,这些就是经常说的“动态链接库”,DLL 是Dynamic Link Library(即“动态链接库”)的缩写。

从Microsoft 公司推出首个版本的Windows 以来,动态链接库就一直是这个操作系统的基础。

1.看看DLL 里有什么与其用晦涩的专业术语来解决DLL 是什么,不如先来看看DLL 里有什么。

DLL 和EXE 文件一样,其中包含的也是程序的二进制执行代码和程序所需的资源(比如图标、对话框、字符串等),可是为什么要把代码放在DLL 里面,而不是做成EXE 呢?其实DLL 中的代码是以API 函数形式出现的,通俗地说,DLL 中包含的程序代码都被做成了一个个小模块,应用程序通过按下所需DLL 中特定的按钮,来调用DLL 中这个按钮所代表的功能。

在使用“记事本”等程序时,如果要保存文件或打开文件,就会弹出通用文件对话框,让我们选择文件位置。

你可知道,这就是调用了系统底层DLL 中的通用对话框界面。

2.系统中几个重要的DLLWindows 中有3个非常重要的底层DLL:Kernel32.dll 、User32.dll 、GDI32.dll 。

其中Kernel32.dll 顾名思义就是内核相关的功能,主要包含用于管理内存、进程和线程的函数;而User32.dll 中包含的则是用于执行用户界面任务的函数,比如把用户的鼠标点击操作传递给窗口,以便窗口根据用户的点击来执行预定的事件;GDI32.dll 的名称用了缩写,全称是Graphical Device Interface(图形设备接口),包含用于画图和显示文本的函数,比如要显示一个程序窗口,就调用了其中的函数来画这个窗口。

3.为什么要用DLL刚才在谈到这个问题的时候,我们只是解释了DLL将程序代码封装成函数的原理。

为什么封装成函数,就能成为系统中大量使用DLL的理由呢?①扩展应用程序由于DLL能被应用程序动态载入内存。

所以,应用程序可以在需要时才将DLL载入到内存中,这让程序的可维护性变得很高。

比如QQ的视频功能需要升级,那么负责编写QQ的程序员不必将QQ所有代码都重写,只需将视频功能相关的DLL文件重写即可。

②便于程序员合作这个和我们最终用户关系不大,仅供了解。

我们都知道编程工具有很多,比如VB、VC、Delphi等,如果好几个人合作来编写一个大的程序,那么可能有的人用VB,有的人用VC,每人负责的部分所使用的编程语言都不同,究竟放在哪个编译器中进行编译呢?这就好比一群来自各个国家的人在共同编写一篇文章,如果他们所使用的语言都不同,写出来的文章怎么可能凑到一起呢?而有了DLL后,可以让VC程序员写一个DLL,然后VB程序员在程序中调用,无需为怎么将它们都编译为一个单独的EXE而发愁了。

③节省内存如果多个应用程序调用的是同一个动态链接库,那么这个DLL文件不会被重复多次装入内存中,而是由这些应用程序共享同一个已载入内存的DLL。

就好比一个办公室中,很少会为每一个员工配置一台饮水机的,而是在一个公共位置放上一个饮水机,所有需要喝水的职员都可以共用这台饮水机,降低了成本又节约了空间。

④共享程序资源包括刚才提到过的通用文件对话框在内,DLL文件提供了应用程序间共享资源的可能。

资源可以是程序对话框、字符串、图标,或者声音文件等。

⑤解决应用程序本地化问题在下载了某个程序的汉化包后,打开汉化说明,经常可以看到用下载包中的DLL文件覆盖掉程序原来的DLL,汉化就完成了。

这些程序都是将执行代码和应用程序界面分开编写了,所以汉化者只需简单地将其中和程序界面相关的DLL汉化并发布即可。

求知若渴:探究DLL的真相谁知道DLL里究竟有多少函数,又有谁知道EXE调用了哪个DLL的哪些函数?其实,这个问题并不难解决。

分析EXE文件的工具Dependency Walker(以下简称Depends,下载地址/development/c/33145.html)?今天我们要用它当探险工具,把DLL真相探个通通透透。

1.看看DLL里有多少函数第一步:下载并解压Depends,运行其中的depends.exe,然后选择菜单“File→Open”(文件→打开),在文件选择框中选中需要分析的DLL文件并打开,此处选择QQ目录下的QQZip.dll。

第二步:在程序左侧的树状栏中就列出了这个DLL使用了哪些其他DLL的功能函数(原来DLL中还可以调用其他DLL^O^),而右侧的两个分栏列表分别显示了函数输入及输出表,函数输出表即为该DLL提供给其他EXE或者DLL调用的函数的总列表。

第三步:函数输出表的Function栏中即为输出函数的名称(见图1),在QQZip.dll中共发现了2个函数:Unzip、Zip。

因此可以判断该DLL在QQ程序中负责压缩和解压缩的任务。

2.审审EXE究竟用了哪个DLL还是拿QQ来作为例子,在Depends中打开QQ.exe,这时界面左侧的树状列表中显示的就是QQ.exe调用的DLL列表(见图2),如果展开这些DLL分支,还会发现其他的DLL,这就说明QQ调用的这些DLL文件还有可能(几乎是肯定)再调用别的DLL。

这就好比买了一台新的DVD机,可能其中用的机芯是SONY的,而这个机芯里的一个小电容又有可能是别的公司的,这是同样的道理。

3.用DLL看穿EXE真面目刚才得到了QQ.exe所使用的DLL列表,其实通过这个列表,还能分析出很多别的信息。

比如其中包含MFC42.dll,所以可以判断QQ.exe是采用VC(即Visual C++)编写的,而包含WSOCK32.dll则说明这个程序带有网络通讯功能(废话!QQ如果不能网络通讯还有什么用……)。

以下是一个简表,大家在分析别的EXE时可以根据其所使用的DLL来对其功能进行初步判断。

DLL文件名可以判断出的EXE信息MFC42.dll 使用VC5.0/6.0编写。

VBRun*.dll “*”代表数字版本号,使用VB3.0/4.0编写。

MSVBVM50.dll 使用VB5.0编写,在Windows 98(SE)上自带该DLL。

MSVBVM60.dll 使用VB6.0编写,在Windows Me/2000/XP等系统上自带该DLL。

ADVAPI32.dll 可能会进行注册表操作。

WSOCK32.dll 具备网络通讯功能。

WS2_32.dll 具备网络通讯功能。

WININET.dll 具备HTTP浏览、下载等功能,典型的例子是浏览器、下载工具。

WINMM.dll 具备多媒体播放能力。

DDRAW.dll 游戏、高级图像处理工具。

D3D*.dll 3D游戏,或者动画处理工具。

4.DLL是个大宝库除供应用程序调用函数的DLL外,还有另一种用来保存资源的DLL,比如QQ目录下的QQRes.dll,用Depends打开后发现没有任何输出函数,难道是一个鸡肋DLL?可是改用资源工具Resource Hacker(下载地址:/development/reference/8312.html)打开这个DLL后,就发现原来其中保存了这么多QQ的资源,包括图标、音乐、图片、字符串、对话框……(见图3)刨根问底:DLL的寓言DLL引起的故障是很常见的,为什么会引起故障?遇到故障怎么解决?嘘~偷听一下DLL的对话,你就会明白了。

1.从搬运工谈接口兼容性在Windows工地上,有一个名叫EXE的包工头,他手下有很多称为DLL的建筑工人。

其中有一个专门负责搬运的DLL(暂且称为“搬运工A”),每次需要搬运水泥时,包工头EXE 都只要对他喊一声:“来!搬。

”过了一段时间,搬运工A觉得自己的效率太低,于是从原来的每次搬1袋水泥改成了每次搬3袋水泥。

改进了搬运方法后,EXE包工头仍然每次只是喊一声:“来!搬。

”却不知搬运工A已经改变了搬运的方法。

但又过了一段时间,包工头EXE把搬运工A给辞退了,从别的工地上找来了另一个DLL(暂且称为“搬运工B”)。

这个搬运工在别的工地的时候,搬运东西特别快,所以包工头EXE决定把搬运工作给“升级”一下。

但真正开始工作时,包工头才发现出了问题……现在不管叫几遍“来!搬。

”这个新来的搬运工B都不知道究竟应该搬什么。

上面的例子中,搬运工A改进搬运方法,但EXE调用它的方法仍不变,这就是DLL升级的原理,改进了内部的实现方法,但调用接口不变,这样EXE文件不用跟着升级,就能调用新版本的DLL了。

而搬运工B的故事告诉我们,不管新版本的DLL效率多高,如果接口(可以理解为DLL中输出的函数名)与原来的不一致,那么EXE就不知道也无法调用它了。

2.登记身份证的DLL在系统故障中,有很多都是由于DLL文件没有注册造成的,比如Windows XP的压缩文件夹功能出现故障就很有可能是系统目录中的zipfldr.dll没有注册造成的,这类故障的解决方法也大多是运行如下命令:regsvr32 DLL文件名很多人不理解为什么要这么做,是不是所有的DLL都能这样做呢?其实系统中有两种DLL,一种是不需注册即可使用的,另一种则是必须经过系统登录(即注册)才能使用的。

就好像一个临时工,和一个记录在员工名单上的长期合同工的区别一样。

如何才能区分这两种DLL呢?方法很简单,用刚才的Depends打开这个DLL,同样是看函数输出表,如果其中包含以下两个函数(前者是注册DLL,后者是反注册DLL),那么就一定是需要注册才能使用的DLL了。

DllRegisterServerDllUnregisterServer而regsvr32这个命令,实际上就是调用DLL中的这两个函数(“regsvr32 /u DLL文件名”调用的即为DllUnregisterServer反注册函数)。

3.插件DLL的秘密Winamp、Foobar 2000等很多软件都具有插件功能,从网上下载一个DLL放在插件目录下就能让程序支持新的功能,这是怎么做到的呢?就拿时下流行的播放软件“千千静听”来举例吧。

“千千静听”的插件目录在该软件安装目录下的Addin子目录下,程序的插件目录一般都会以“Plugins”、“Addin”来命名。

在“千千静听”的插件目录中有许多DLL文件,比如tt_asf.dll、tt_rm.dll等,从文件名中就能看出这些DLL是用来让这个播放器支持各种不同类型的音频文件的。

同样,用Depends打开这些文件,你就会发现这些文件的输出函数表中都包括一个同样的函数:ttpGetSoundAddIn(见图4)。

相关文档
最新文档