⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 动态链接库.txt

📁 vc学习记录
💻 TXT
字号:
4.1 动态链接库(DLL)的概述
4.1.1 DLL的定义 4.1.2 DLL的种类
4.1.3 动态链接库和静态链接库的比较
4.2 DLL的基本理论
4.2.1 DLL入出口函数 4.2.2 DLL的链接方式
4.2.3 DLL动态链接库库函数的导出
4.2.4 从DLL中导出数据变量
4.3 用VC++开发环境生成DLL
4.3.1 用VC++生成WIN32 DLL
4.3.2 用VC++的MFC生成的 DLL
4.4 使用DLL
4.4.1 DLL的使用 4.4.2 DLL的调试
4.5 用VC++工具开发DLL的编程实例
4.1 动态链接库(DLL)的概述
DLL特点:要求一个DEF文件;要求一个DllMain()的入口点,不是WinMain();DLL可以装入,但不能执行. 
4.1.1 DLL的定义 
动态链接库:是应用程序中的一段程序,将它放在一个不同的容器内,是一个可以从主.exe文件中单独执行的模块.可以认为一个DLL就是其它应用程序在执行时,能够动态链接和调用的一组服务或函数.
DLL中存放的一般是一些公共的子程序段或各种资源和数据.一个最大的特点:可以实现应用程序本地化.如在DLL中封装了各种语言,在安装时进行适当的选择就能实现本地化.
4.1.2 DLL的种类
主要有Win32 DLL和MFC APPWizard DLL两大类及相关子类.
4.1.3 动态链接库和静态链接库的比较
一个应用程序和函数的链接方式有两种:
动态链接:在应用程序中不需要包含所要调用函数的代码,而只需要所调DLL函数的一些信息,如DLL位置及相应的函数名.与函数的链接到编译或运行时进行.
静态链接:应用程序必须从静态链接库中取得所需调用函数的代码,并把这些代码放在应用程序的可执行代码中.如一般的库函数调用则属此类.
DLL的特点:
有利于不同的应用程序共享数据和资源;
多个应用程序可以使用内存中的动态链接库的单一映射,从而节约了程序运行和内存空间;
通过使用动态链接库,应用程序可以拆分为相对独立的功能模块,有利于应用程序的升级;
当多个应用程序需要使用相同的函数时,通过使用动态链接库,可以节约大量的硬盘空间.
4.2 DLL的基本理论
应用程序在使用DLL中的内容之前,系统要调用入出口函数完成DLL的初始化和终止工作.
4.2.1 DLL入出口函数
1,DllMain函数:在一个DLL的调用和撤除时被调用,一般发生在应用程序使用LoadLibrary 和FreeLibrary等函数及进程经线程启动和终止时.函数结构为:
BOOL APIENTRY DllMain(HINSTANCE hInstance, DWORD fdwReason , LPVOID lpvReserved){
Switch (fdwReason){
Case DLL_PROCESS_ATTACH:break;/DLL映射到进程地址空间
Case DLL_THREAD_ATTACH:break;/一个线程被创建
Case DLL_THREAD_DETACH:break;/线程退出
Case DLL_PROCESS_DETACH:break;}/DLL从进程中解除映射
Return TRUE;}
其中hInstance是DLL的模块句柄, lpvReserved 指定DLL初始化和清除的一些内容指针,fdwReason表明调用DllMain()函数的原因,具体如下: 
在应用程序终止或显式调用FreeLibrary()使DLL脱离进程的地址空间时发送
0
DLL_PROCESS_DETACH
在连接DLL的进程中一个线程终止时发送
3
DLL_THREAD_DETACH
在连接DLL的进程中生成一个新线程时发送
2
DLL_THREAD_ATTACH
当一个DLL首次装入进程的地址空间时发送
1
DLL_PROCESS_ATTACH
含义
标志
2 . MFC的 Regular DLL 入出口
在MFC的DLL使用中,已编好了DllMain()函数,用户不必写,在装载DLL时调用其成员函数InitInstance,在DLL退出时调用成员函数ExitInstance, 所需要的初始化和终止工作在这两个函数中完成.
4.2.2 DLL的链接方式
DLL中包含一个或多个函数,调用这些函数的过程和编译,链接的过程是独立的.有两种链接方式:隐式链接和显式链接.
隐式链接DLL
原理:先说明DLL的导入库文件(lib),因在库文件中包含了一系列指向动态链接库的指针.应用程序通过库文件和DLL链接,调用DLL中的函数.
应用程序在调用DLL时需以下信息:
包含导出函数以及类声明的头文件,需要知道函数名和函数接口信息.
DLL的导入库文件,应用程序在编译链接需要.
实际的DLL文件,应用程序在运行时调用它.
显式链接DLL
原理:应用程序在运行时通过函数调用来显式装载和卸载DLL,并通过函数指针来调用DLL的导出函数,这种方式主要用于灵活控制DLL库动态装入和装出的场合.
使用:第一步调用函数LoadLibrary或AfxLoadLibrary装载DLL并得到模块句柄.原型如下:
HINSTANCE LoadLibrary(LPCSTR lpLibFileName);
参数为要装入的DLL的文件名字.当此函数被多次调用时,在进程中只有一份DLL程序和数据,系统通过计数器来标识. 
第二步:调用函数GetProcAddress来获得导出函数的指针.函数原型如下:
FARPROC GetProcAddress(HMODULE hModul,LPCSTR lpProName);
hMoudul是DLL的实例句柄,参数lpProName是相应的函数名.
第三步:在使用完后调用函数FreeLibrary或AfxFreeLibrary 来释放DLL. FreeLibrary原型为
BOOL FreeLibrary(HINSTANCE hInstLib);
参数是装入的DLL模块的句柄,调用一次,DLL计数器值减一,最终回到0,系统释放被DLL占用的空间.
4.2.3 DLL动态链接库库函数的导出
动态链接库中的函数可以分为导出函数和内部函数.
动态链接库中的函数主要有以下几种:
(1)在源程序中使用关键字:_declspec(dllexport).
此函数可从一个DLL中输出数据,函数,类,类成员函数而不需要DEF文件.
原理:根据一个指定的存储类属性(extended-attribute)存储某个项数据.其属性主要有:allocate("segname"),
dllimport,dllexport,naked等,语法如下:
_declspec(extended_attribute) declarator;具体使用有二种情况:_declspec(dllexport) void_cdecl Function1(void);
Class _declspec(dllexport) CExportCLass:public Cobject
{……..}
(2) 在DEF文件中通过EXPORTS来声明函数
DEF是由一个或多个描述DLL属性的语句组成的文本文件,主要有:
LIBRARY语句:用于指定DLL的内部名;
DESCRIPTION语句:用于描述DLL特性;
SECTIONS语句:用于设置段的属性,这些属性有:
READ,WRITE,EXECUTE,SHARED;
EXPORTS语句:用于列出被导出的函数名及相关信息;
VERSION语句:该DLL的版本号.
例:
LIBRARY "Dll"
DESCRIPTION 'Dll Windows Dynamic Link Library'
EXPORTS
Function1 @1
Function2 @2
Function3 @3
EXPORTS ……….
……….
库函数的声明如下:
Entryname[=internalname] [@ordinal[NONAME]]
外部名 内部名 序号 不输出函数名
4.2.4 从DLL中导出数据变量
(1)使用DEF文件,设置关键字CONSTANT导出.通过用CONSTANT标志时,表明前面导出的不是函数,而是一个数据变量.
EXPORTS
Bvariable @4 CONSTANT
Extern BOOL bVariable ;//程序中的应用
(2)可以在应用程序中使用关键字 _declspec(dllimport)
引入对DLL导出的变量的作用,在DLL源程序中以_declspec(dllexport)来说明要导出的变量.
4.3 用VC++开发环境生成DLL
4.3.1 用VC++生成WIN32 DLL
Win 32的DLL自动生成过程:
FILE->NEW->PROJECT->Win32 Dynamic-Link Library->ok,然后选择相应的类型工程.
2. DLL工程类型:
(1)空DLL工程
在需要时编写程序源文件,和DEF文件
(2)简单的DLL工程
只有DllMain(),没有导出和其它变量或函数,不生成DEF文件,编译后也不产生LIB文件.
(3)导出变量,函数和类的DLL
较为详细地建立了DLL中的一些基本成分,包括导出关键字_declspec(dllexport),生成LIB文件.
4.3.2 用VC++的MFC生成的 DLL
MFC类库的DLL自动生成过程:
FILE->NEW->PROJECT->MFC AppWizard(dll) -> ok,然后选择相应的类型工程.
2. MFC AppWizard DLL类型:
(1)静态链接MFC的 Regular DLL
在内部使用MFC的DLL库,可被MFC和非MFC的应用程序使用,若在工程建立时使用的是MFC静态库,导出函数使用标准C语言接口,创建时自动生成DEF文件,如导出函数:MyExportFunction()用:
extern "c" EXPORT MyExportFunction();
(2)动态链接MFC 的Regular DLL
动态链接MFC 的Regular DLL和静态链接MFC 的Regular DLL基本相似,最后都是由CWinApp派生类的成员函数InitInstance和ExitInstance来完成DLL的初始化和应用程序调用结束时的终止,清理工作.
不同的是:DLL在建立时用的是MFC的动态共享库.其导出函数的开头部分使用AFX_MANAGE_STATE宏.
(3)动态链接MFC 的扩展 DLL
MFC 的扩展(Extension) DLL是从已有的MFC类派生新类的DLL,它建立时作用MFC动态链接库,它的导出函数只能由使用MFC动态共享库的MFC应用程序调用.
注:如果显示链接到这种DLL的应用程序是多线程的,则应使用AfxLoadLibrary 和AfxfreeLibray来装载和卸载扩展DLL,而不要用AfxLoadLibrary 和AfxfreeLibray.
4.4 使用DLL
4.4.1 DLL的使用
调用DLL的应用程序在没有指定DLL位置时,默认位置如下:
(1)含有该应用程序的目录
(2)当前执行所在目录
(3)Windows的系统目录,如system目录
(4)Windows目录
(5)在环境变量PATH中列出的目录
4.4.2 DLL的调试
(1)使用应用程序调试DLL
打开应用程序的工程, 选择Project->settings-> debug-> category->additional DLLs->指定调试的DLL文件.
(2)使用DLL的工程调试DLL
打开DLL工程, 选择Project->settings-> debug -> category->additional DLLs->指定调试的DLL文件.
此时可以设置断点进行调试.
(3)同时使用应用程序和DLL调试DLL
可以在同一个工作区中打开应用程序工程和DLL工程,如下:
选择Project->Insert Project into Workspace-> Win32 debug 进行DLL程序调试.
4.5 用VC++工具开发DLL的编程实例
(见P93-P102)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -