210 likes | 353 Views
项目 12 :动态链接库-在 PDA 研发中使用 DLL 文件( 1 ). 本节课程主要知识点 动态链接库 动态链接库的特点 动态链接库的实现. 重点和难点. 重点 动态链接库 难点 动态链接库的编制. 动态链接库. EXE 文件. 比较大的应用程序都由很多模块组成,这些模块分别完成相对独立的功能,它们彼此协作来完成整个软件系统的工作。 可能存在一些模块的功能较为通用,在构造其它软件系统时仍会被使用。 在构造软件系统时,常常将所有模块的源代码都静态编译到整个应用程序 EXE 文件中。. EXE 文件的软肋.
E N D
项目12:动态链接库-在PDA研发中使用DLL文件(1)项目12:动态链接库-在PDA研发中使用DLL文件(1) 本节课程主要知识点 • 动态链接库 • 动态链接库的特点 • 动态链接库的实现
重点和难点 重点 • 动态链接库 难点 • 动态链接库的编制
EXE文件 • 比较大的应用程序都由很多模块组成,这些模块分别完成相对独立的功能,它们彼此协作来完成整个软件系统的工作。 • 可能存在一些模块的功能较为通用,在构造其它软件系统时仍会被使用。 • 在构造软件系统时,常常将所有模块的源代码都静态编译到整个应用程序EXE文件中。
EXE文件的软肋 • 源代码都静态编译到整个应用程序EXE文件中,会产生一些问题。 • 一是增加了应用程序的大小,占用更多的磁盘空间,程序运行时也会消耗较大的内存空间,造成系统资源的浪费。 • 另一个缺点是,在编写大的EXE程序时,在每次修改重建时都必须调整编译所有源代码,增加了编译过程的复杂性,也不利于阶段性的单元测试。
Windows CE中如何解决问题? • Windows CE中内存资源更少,甚至都没有硬盘,资源问题更为突出。 • Windows系统平台上提供了一种有效的编程和运行环境,你可以将独立的程序模块创建为较小的文件,并可对它们单独编译和测试。 • 这些较小的模块就是动态链接库DLL。
Windows CE中的DLL • 在运行时,只有当EXE程序确实要调用这些DLL模块的情况下,系统才会将它们装载到内存空间中。 • Windows自己就将一些主要的系统功能以DLL模块的形式实现。
动态链接库(Dynamic Link Library) • 动态链接库缩写为DLL。 • DLL是一些编译过的可执行程序模块、数据或其他资源,可以被应用程序或其他DLL调用。 • DLL的应用非常广泛,可以实现多个应用程序的代码和资源共享。
动态链接库的组成 • DLL是一种磁盘文件,以dll、DRV、FON、SYS和许多以EXE为扩展名的系统文件都可以是DLL。 • 它由全局数据、服务函数和资源组成,在运行时被系统加载到进程的虚拟空间中,成为调用进程的一部分。 • 如果与其它DLL之间没有冲突,该文件通常映射到进程虚拟空间的同一地址上。
动态链接库的几点注意 • DLL中包含各种导出函数,用于向外界提供服务。 • DLL有自己的数据段,但没有自己的堆栈,使用与调用它的程序相同的堆栈。 • 一个DLL在内存中只有一个实例。 • DLL的编制与具体的编程语言及编译器无关。
共享资源 • 共享代码、资源和数据。DLL不仅可以包含可执行的代码,还可以包括数据和各种资源等,扩大了库文件的使用范围。
方便应用程序的扩展 • 由于DLL能被应用程序动态载入内存。所以,应用程序可以在需要时才将DLL载入到内存中,这让程序的可维护性变得很高。 • 比如微软的操作系统经常需要升级,微软的程序员不必将操作系统代码都重写一遍,只需将需要升级的相关DLL文件重写即可。
DLL与语言无关 • 一个小组成员共同完成一个软件项目。每个人所使用的编程工具并不同,每人负责的部分所使用的编程语言都不同,如何合作完成项目呢? • 使用DLL就可以解决这个问题,程序员提供自己完成代码的DLL即可,主程序调用这些DLL即可。
节省内存 • 如果多个应用程序调用的是同一个动态链接库,那么这个DLL文件不会被重复加载到内存中,而是由这些应用程序共享同一个已载入内存的DLL。 • 在一个办公室中,一般大家会共用一个网络打印机,不会为每一个员工配置一台打印的。 • 在嵌入式系统中更有意义。
隐藏程序的细节 • 在某些情况下,用户可能想隐藏程序的源代码,就可以采用DLL来实现,DLL的例程可以被应用程序访问,而不显示其中代码的细节。 • 可以有效地保护自己的知识产权。
节省内存 • 如果多个应用程序调用的是同一个动态链接库,那么这个DLL文件不会被重复加载到内存中,而是由这些应用程序共享同一个已载入内存的DLL。 • 在一个办公室中,一般大家会共用一个网络打印机,不会为每一个员工配置一台打印的。 • 在嵌入式系统中更有意义。
DLL入口函数 • 每一个DLL必须有一个入口点,DLLMain是一个缺省的入口函数。 • DLLMain负责初始化(Initialization)和结束(Termination)工作,每当一个新的进程或者该进程的新的线程访问DLL时,或者访问DLL的每一个进程或者线程不再使用DLL或者结束时,都会调用DLLMain。
DLLMain的函数原型 • int WINAPIDLLMain(HINSTANCE hinstance,DWORD fdwReason,PVOID pvReserved) • { switch(fdwReason) • { case DLL_PROCESS_ATTACH: • case DLL_THREAD_ATTACH: • case DLL_THREAD_DETACH: • case DLL_PROCESS_DETACH: • return TRUE; • } • }
DLLMain的函数的参数 • hinstance是动态库被调用时所传递来的一个指向自己的句柄。 • fdwReason是一个说明动态库被调原因的标志。当进程或线程装入或卸载动态连接库的时候,操作系统调用入口函数,并说明动态连接库被调用的原因。它所有的可能值为 • DLL_PROCESS_ATTACH 进程被调用 • DLL_THREAD_ATTACH 线程被调用 • DLL_PROCESS_DETACH 进程被停止 • DLL_THREAD_DETACH 线程被停止 • lpReserved是一个被系统所保留的参数。