动态链接库程序的编写(VC++学习笔记)

使用动态链接库的好处:

1.        可以采用多种编程语言来编写.

2.        增强产品的功能.

3.        提供二次开发的平台.

4.        简化项目管理.

5.        可以节省资源的共享.

6.        有助于实现应用程序的本地化.

 

编写一个DLL(动态链接库),和编写一个我们自己的函数库一样,唯一不同的是,它被编译器编译成了DLL文件.而这个文件,可以被我们日后的系统所调用,不再需要对其重新编译.

 

使用VC++开发平台来创建一个动态库非常方便,方法如下:

新建工程->Win32 Dynamic-Link Library 然后输入工程名字.

然后新建C++ source 文件来编写我们的函数.

最后编译链接即可得到我们所编写的DLL.

我们发现生成了两个文件.一个dll文件和一个lib文件.lib(输入库)文件给我们,这个输入库文件它并没有包括实现的代码,而只是为我们的链接程序提供信息,以便在我们的可执行文件,也就是exe文件建立动态链接时,要用到的重定位表.

注意:我们在编写函数代码时,需要在函数前加上_declspec(dllimport).

规定此函数将被导出.

Code Section:

_declspec(dllimport) int add(int a, int b){
	return a + b;
}
_declspec(dllimport) int subtract(int a, int b){
	return a - b;
}

 

使用一个动态链接库:

方法1.

将我们所需要使用的dll文件放在客户代码工程目录下,或者放在系统的环境变量所指定的目录中.

然后打开Project->Setting->LinkObject/library modules处输入随DLL库提供给我们的lib文件.

显示声明一下我们所使用的函数是外部导入的.代码如下:

Code Section:

extern add(int a, int b);
extern subtract(int a, int b);

最后,我们就可以使用DLL给我们提供的addsubtract函数了.

 

方法二.

在创建动态链接库时,为所有的函数在头文件进行声明.

然后把头文件提供给用户,当然我们可以在头文件对库函数进行详细的描述.

这里我们就不需要在外部进行extern声明了,只把头文件进来即可..

头文件格式如下:

CodeSection:

#ifdef DLL_API
#else
//防止在C语言客户端访问C++编译器编译而成的DLL,因为C++编译器会对DLL
//内的函数进行改编,对C编译来说是不可识别的,所以在这里我们在显示的
//申明一下使用C规则来进行导入,但这样不能对类成员进行导入进出
//#define DLL_API extern "C" _declspec(dllimport)
#define DLL_API _declspec(dllimport)
#endif

#include <windows.h>
#include <stdio.h>

DLL_API int add(int a, int b);
DLL_API int subtract(int a, int b);

class DLL_API Point
{
public:
	void output(int x, int y);
};

方法三:

此方法采用动态的方法来对DLL进行加载,不需要在进行加载时将所有的库一次性的全部加载进来,而是在需要使用时,才进行动态的增加.如果不采用动态加载的办法,而是像我们上面所介绍的方法那样,在加载的库比较多的情况下,这样会增加进程的启动时间,导致软件启动减慢.

在使用动态加载中,不需要任何的外部声明,也不需要增加在添加任何的输入库文件,就可完成DLL库的动态加载.

Code Section:

 

HINSTANCE hInst;
	hInst = LoadLibrary("Dll2.dll");//Dynamice loading Dll2.dll
	typedef int (*ADDPROC)(int a, int b);//Define pointer function
	ADDPROC add = (ADDPROC)GetProcAddress(hInst, "add");//Get function address of add
	if(!add){
		MessageBox("获取函数失败");
		return;
	}

注意::如果在这里我们没有通过模块定义文件来定义函数改编后的名称,那么我们这里所要获取的函数名不是DLL的函数名,而应该是经过编译器改变后的函数名.: ?add@@YAHHH@Z

GetProcAddress() 第二个参数,除了指定是函数名外,也可以是所需调用函数的序号,这个序号我们可以使用dumpbin -exports DLLNAME(微软提供给我们的工具)来查看,由于第二个参数是需要一个指向常量的字符串,而这时辰 我们所得到的是一个整形,所以我们可以使用MAKEINTRESOURCE(INT)这个宏来进行转变.

 

当我们不再需要动态链接库的时候,那么可以使用FreeLibrary(hinst)来释放我们所加载的动态链接库资源.

 

机器人 2007-06-24 北京

 

此条目发表在 c/c++ 分类目录,贴了 , , , 标签。将固定链接加入收藏夹。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>