VC++程序设计与应用--动态链接库
Posted Abro.
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了VC++程序设计与应用--动态链接库相关的知识,希望对你有一定的参考价值。
目录
1.2.2 使用关键字_declspec(dllexport)
前言
本篇文章介绍动态链接库
一、动态链接库
1.1 概述
在多任务环境中,为了提高系统资源的利用率和系统的整体性能,应该使每一个应用程序尽量少占用系统内存等资源。
动态链接库便是这一设想的体现,允许多个应用程序同时共享动态链接库在内存中的同一份拷贝。
1.1.1 动态链接库的概念
动态链接库(DLL):一种用来为其它可执行文件(包括EXE文件和其它DLL)提供共享的函数库。
DLL中一般定义有两种类型的函数:导出函数和内部函数。导出函数是可以被外部程序调用的函数,内部函数只能在DLL内部使用。
1.1.2 动态链接库和静态链接库的区别
动态链接库和静态链接库的主要区别是与应用程序的链接方式不同,前者进行的是动态链接,后者进行的是静态链接。
1.1.3 使用动态链接库的优点
(1) 实现多个应用程序共享数据和代码的方式。
(2) 提高应用程序的执行效率和运行速度。
(3) 方便应用程序的升级和售后支持。
(4)把应用程序所使用的资源,如图标、位图、字符串和对话框等,独立出来做成DLL,为多个应用程序所共享。
(5) 动态链接库便于建立多语言的应用程序。
1.1.4 DLL文件的存放位置
程序所需的DLL文件必须位于下面4个目录之一中:
(1) 当前目录
(2) Windows的系统的目录,如Windows\\system
(3) Windows所在的目录,如WINNT
(4) 环境变量PATH中所指定的目录
1.1.5 动态链接库的分类
Visual C++ 6.0支持多种DLL,包括:
- 非MFC DLL
一般来说,非MFC DLL的内部不使用MFC,非MFC DLL的导出函数都使用标准的C接口,因此无论应用程序是否使用了MFC,都可以调用非MFC DLL。
- MFC扩展DLL
MFC扩展DLL一般用来提供派生于MFC的可重用的类,以扩展已有的MFC类库的功能。MFC扩展DLL使用MFC的动态链接版本。只有使用MFC生成的可执行程序(无论是EXE还是DLL)才能访问MFC扩展DLL。
1.2 创建MFC DLL
利用MFC AppWizard[dll]向导可以创建MFC DLL。 DLL文件与可执行文件非常相似,不同点在于DLL包含有导出表。导出表包含DLL中每个导出函数的名字,这些函数是进入DLL的入口点。只有导出表中的函数可以被外部程序调用。
从MFC DLL中导出函数常用以下两种方法:使用模块定义文件(.def)和使用关键字_declspec(dllexport)。
1.2.1 使用DEF文件
DEF文件是一个包含EXE文件或DLL文件声明的文本文件。每个DEF文件至少必须包含LIBRARY语句和EXPORTS 语句,其他语句可以省略。
DEF文件常用的模块语句如下:
- 第一个语句必须是LIBRARY语句,这个语句指出DLL的名字,链接器将这个名字放到DLL导入库中,DLL导入库包含了指向外部DLL的函数索引指针。
- EXPORTS 语句列出被导出函数的名字, 以及导出函数的数值(由@号与数字构成)。序数值可以省略,编译器会为每个导出函数指定一个,但这样指定的值不如自己指定的明确。
- 使用DESCRIPTION语句描述DLL的用途,这个语句可以省略。
- 使用“;”开头的注释语句。
1.2.2 使用关键字_declspec(dllexport)
从MFC DLL中导出函数的另一种方法是在定义函数时使用关键字_declspec(dllexport)。这种情况下,不需要DEF文件。导出函数的形式为:
declspec(dllexport) <返回类型> <导出函数名>(<函数参数>);
1.2.3 两种导出函数方法的比较
- 如果需要使用导出顺序值,那么应该使用DEF文件来导出函数。
- 使用DEF文件来导出函数,可以创建具有NONAME属性的DLL。
- 使用declspec(dllexport)关键字导出函数不需要编写DEF文件,因此,如果编写的DLL只供自己使用,使用__declspec(dllexport)较为简单。
1.3 使用MFC DLL
应用程序与DLL链接后,DLL才能通过应用程序调用运行。应用程序与DLL链接的方式主要有如下两种:隐式链接和显式链接。
隐式链接又称为静态加载,指的是使用DLL的应用程序先链接到编译DLL时生成的导入库LIB文件,执行应用程序的同时操作系统自动加载所需的DLL。在应用程序退出之前,DLL一直存在于该程序运行进程的地址空间中。
显式链接又称为动态加载,使用显式链接DLL的应用程序必须在代码中动态地加载所使用的DLL,并使用指针调用DLL中的导出函数,在使用完毕后,应用程序必须卸载所使用的DLL。
1.3.1 使用隐式链接
使用隐式链接除了需要相应的DLL文件外,还必须具备以下2个文件:
- 包含导出函数以及类声明的头文件
- DLL的导入库LIB文件
编译时将DLL的LIB文件加入应用程序中,主要有如下3种方法。
- 在主菜单project中,选择菜单项【Add To Project| Files】菜单项,在弹出的Insert Files Into Project对话框中选择所需的LIB文件。
- 在程序的StdAfx.h头文件中加入下列语句:#pragma comment (lib,"指定的LIB文件名")
- 在主菜单project中,选择【Settings】菜单项,弹出Project Settings对话框,如下图所示。选择Link选项卡,在Object/library modules文本框中输入指定的LIB文件名,多个库文件之间用空格分开。
1.3.2 使用显式链接
使用显式链接时,需要知道导出函数返回值的类型和所传递的参数个数、类型和顺序等。应用程序在调用DLL中的导出函数前,必须首先调用LoadLibrary()函数加载DLL并得到一个模块句柄,然后使用得到的模块句柄调用GetProcAddress()函数获取导出函数的指针,并使用该指针调用DLL中的导出函数。DLL使用完毕后,调用FreeLibrary()函数释放加载的DLL。
若DLL是MFC扩展DLL,则应用程序应该分别使用AfxLoadLibrary()和AfxFreeLibrary()函数来加载和释放DLL。
1.4 MFC拓展DLL
MFC扩展DLL的含义在于它是MFC的扩展,其主要功能是实现从现有MFC类库中派生出可重用的类。
1.4.1 创建MFC扩展 DLL
对于MFC扩展DLL,系统会自动在项目中添加如下表所示的宏,这些宏为DLL和应用程序的编写提供了方便。 例如MFC扩展DLL除了可使用关键字_declspec(dllexport) 导出类外,还可以使用宏AFX_EXT_CLASS来导出类,而链接到MFC扩展DLL的可执行文件同样使用这个宏来导入类。
总结
机会就像坐公交车,有人上车早,有人上车晚,有人直达车,有人要转车。只要你有决心去目的地,一定可以找到自己的路线!
以上是关于VC++程序设计与应用--动态链接库的主要内容,如果未能解决你的问题,请参考以下文章