210 likes | 417 Views
项目 12 :动态链接库-在 PDA 研发中使用 DLL 文件( 2 ). 本节课程主要知识点 动态链接库的加载 动态链接库的静态加载 动态链接库的动态加载. 重点和难点. 重点 动态链接库的加载方法 难点 静态调用中建立关联. 动态链接库的加载. 动态链接库的加载. 动态链接库的加载分为即静态加载方式和动态加载方式。 静态加载方式是在编译程序代码时即完成对 DLL 的加载,应用程序结束时卸载 DLL 。 动态加载方式是使用用 API 函数来加载和卸载 DLL 的。. 动态链接库的静态加载. 动态链接库的静态加载.
E N D
项目12:动态链接库-在PDA研发中使用DLL文件(2)项目12:动态链接库-在PDA研发中使用DLL文件(2) 本节课程主要知识点 • 动态链接库的加载 • 动态链接库的静态加载 • 动态链接库的动态加载
重点和难点 重点 • 动态链接库的加载方法 难点 • 静态调用中建立关联
动态链接库的加载 • 动态链接库的加载分为即静态加载方式和动态加载方式。 • 静态加载方式是在编译程序代码时即完成对DLL的加载,应用程序结束时卸载DLL。 • 动态加载方式是使用用API函数来加载和卸载DLL的。
动态链接库的静态加载 • 静态加载方式由编译系统完成对DLL的加载。 • 应用程序完成对DLL的卸载。 • 加载方法简单,但不够灵活。
LIB文件用来做什么? • 在生成一个DLL文件时,链接程序会自动生成一个与之对应的LIB文件。 • LIB文件包含了每一个DLL导出函数的符号名和可选的标识号,但是并不含有实际的代码。
编译应用程序 • 把生成动态连接库时生成的LIB文件和DLL文件加入到应用程序的工程中。 • 通过静态链接方式编译生成应用程序时,应用程序中的调用函数与LIB文件中导出符号相匹配,这些符号或标识号进入到生成的EXE文件中。 • LIB文件作为DLL的替代文件被编译到应用程序工程中。
DLL中函数的调用(1/2) • 当应用程序运行过程中需要加载DLL文件时,Windows CE根据LIB中的信息发现并加载DLL。 • 然后通过符号名或标识号实现对DLL函数的动态调用。
DLL中函数的调用(2/2) • 所有被应用程序调用的DLL文件都会在应用程序EXE文件加载时被加载在到内存中。 • 可执行程序直接通过函数名调用DLL的输出函数,调用方法和程序内部其他的函数是一样的。
DLL如何共享? • DLL静态加载后,系统会建立对该DLL的调用记录。 • 如还有其它程序使用该动态链接库,则Windows CE对DLL的应用记录减1,直到所有相关程序都结束对该DLL的使用时才释放它。
DLL静态加载实例 • 利用PB或VS2005生成动态链库wcedll.dll和wcedll.lib文件。 • 利用EVC创建一个测试工程wcetest,用以测试动态链接库的静态加载。
设置依赖关系 • 将两个库文件wcedll.dll和wcedll.lib拷贝到当前测试工程wcetest所在的文件夹下。 • 选择Projects菜单,选择Setting…,进入Link标签,在Category下拉框中找到Input,在Object/library modules编辑框中添加wcedll.lib一项内容。
运行测试代码 • 编译并下载wcetest.exe,保证代码没有错误。 • 在目标平台上找到wcetest.exe应用程序,双击它,让其运行起来。 • 通过EVC的Remote Process Viewer就可以看到wcetest.exe已经运行,而且wcedll.dll已经加载。
动态链接库的动态加载 • 动态调用方式是由程序员编程使用API函数来加载和卸载DLL。 • 使用上较复杂,但能更加有效地使用内存,是编制大型应用程序时的重要方式。 • 是一般常见的动态链接库的加载方法。 • 在嵌入式系统中更为常见。
如何实现DLL动态调用? • 在应用程序中用LoadLibrary显式的将自己所做的动态连接库调进来。 • 用GetProcAddress()获取想要引入的函数。 • 如同本应用程序自定义的函数一样来调用该引入函数。 • 在应用程序退出之前,用FreeLibrary释放动态连接库。
DLL动态加载实例 • 利用EVC创建一个测试工程wcetest1,用以测试动态链接库的动态加载。 • 与静态调用DLL相比,程序中增加以下代码 • 添加wcedll动态链接库工程的实现函数的定义。 • 利用LoadLibrary API函数动态加载动态链接库,利用GetProcAddress API函数获取需要引用的函数。
测试程序的源代码 • #include <windows.h> • typedef void (*printH) (void); • int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR szCmdLine,int iCmdShow) • { HANDLE hModule=LoadLibrary(TEXT(“wcedll.dll”)); • if(hModule==NULL) • { return 0; } • else • { printH PrintHello= (printH) GetProcAddress(hModule,TEXT("PrintHello")); • PrintHello(); } • FreeLibrary(TEXT("wcedll.dll")); • return 0; • }
运行测试代码 • 编译并下载wcetest1.exe,保证代码没有错误。 • 在目标平台上找到wcetest1.exe应用程序,让其运行起来。 • 通过EVC的Remote Process Viewer就可以看到wcetest1.exe已经运行而且wcedll.dll已经加载。
Windows CE如何定位DLL • 定位DLL的搜索顺序 • 包含EXE文件的目录 • 进程的当前工作目录 • Windows CE系统目录 • Windows CE目录 • 列在Path环境变量中的一系列目录