文档库 最新最全的文档下载
当前位置:文档库 › C++ dll编程入门

C++ dll编程入门

C++ dll编程入门
C++ dll编程入门

Dll入门教程

一、概述

DLL(Dynamic Linkable Library)它提供一些可以直接使用的变量,类和函数。在经历了“无库—静态链接库—动态链接库”的历程后,dll使用十分广泛。

1、静态链接库和动态链接库的异同点

静态链接库和动态链接库都是共享代码,如果采用静态链接库(.lib),lib中的指令最终都会编译到最终的exe文件中,但是若使用动态链接库(. dll),dll中的指令不会编译到exe 文件中,而是在exe文件执行期间,动态的加载和卸载独立的dll文件。

静态链接库和动态链接库另一个区别是动态链接库不能再包含其他动态链接库或静态链接库,而动态链接库不受此限制,动态链接库中可以再包含其他的动态链接库和静态链接库。

2、Dll的一些概念

(1)只要遵循约定的dll接口规范和调用方式,用各种语言编写的dll可以相互调用。(2)dll的分类有三种,Non-MFC DLL(非MFC DLL),MFC Regular DLL(MFC规则DLL)和MFC Extension DLL(MFC拓展DLL)。非MFC DLL不采用MFC类库规则,其导出函数为标准C接口,能被非MFC或MFC编写的应用程序调用;MFC规则DLL包含一个CWinApp的类,但其无消息循环;MFC拓展DLL采用MFC的动态链接库版本创建,它只能被用MFC类库编写的应用程序调用。

二、静态链接库

在介绍动态链接库前先要介绍静态链接库的知识,静态链接库的后缀是.lib。下面的一个例程将介绍如何生成.lib文件和如何调用.Lib

1、如何生成一个.lib文件

1)、建立一个空解决方案,方案名称为StaticLibrary。

2)、添加一个win32项目,类型为Static Library,名称为StaticLib,空项目。

选择win32 project项目类型

选择Static Library 取消precompiled header

3)、在该项目中添加lib.h和lib.cpp文件,两个文件代码如下图所示。

lib.h文件代码如下:

lib.cpp文件中提供一个函数,实现两个整数的相加,返回两数的和。代码如下:

4)、库工程不能单独运行,需要右键点击生成

生成成功后,将在解决方案目录的debug文件夹中生成一个static.lib文件,该文件就是静态库文件。

2、如何调用.lib文件

1)、在解决方案里再添加一个项目,项目名称为StaticLibCall,类型为Win32,控制台程序,选择空项目。

选择console application 和empty project

2)、在项目源文件文件中添加main.cpp文件。

main.cpp文件中添加如下代码:

3)、将刚刚生成的StaticLib.lib文件和lib.h两个文件复制到该项目的目录下。(一般使用静态库时必须提供这两个文件,.h文件提供函数的预定义,而.lib提供函数的实现)

运行程序,结果如下

三、动态链接库

本教程只介绍一种Dll(非MFC DLL)的创建与调用方法。本Dll实现的功能与第2节介绍的静态库实现的功能一样。

1、如何生成一个dll文件

1)、创建dll工程的步骤和上面介绍的建立lib的步骤一样,仅仅在选择类型时需要选择dll。建立工程后,添加DLib.h和DLib.cpp文件

在项目中添加DLib.h和DLib.cpp文件

2)、DLib.h和DLib.cpp代码如下所示:

DLib.h文件

DLib.cpp文件

分析该代码,该工程的.cpp文件中代码和第2节的.cpp中代码完全一样。而.h文件不一

样,该工程的.h文件中对add函数声明前添加了__declspec(impoet)语句,这个语句的含义是声明函数add为dll的导出函数,dll的函数分两种:

(a) DLL导出函数,可供调用dll的应用程序调用

(b) DLL内部函数,只能在DLL程序使用,调用DLL的应用程序无法调用

3)、右键--生成;生成成功后,将在debug文件夹中生成一个DynamicLib.dll文件

2、如何调用.dll文件

dll文件的调用方式有两种,一种是动态调用,一种是静态调用。动态调用时完全由编程者用系统API函数加载和卸载dll,程序员可以决定dll文件何时加载,何时卸载,加载哪个dll文件,将dll文件的使用权完全交给程序员。

静态调用是由编译系统完成对dll文件的加载和应用程序结束时完成对dll的卸载,当调用某dll的应用程序结束时,则windows系统对该dll的应用记录减1,直到使用该dll的所有应用程序都结束,即对该dll应用记录为0,操作系统会卸载该dll,静态调用方法简单,但不如动态调用适用。

(1)、动态调用dll

1)、新建控制台项目,添加main.cpp文件,将刚刚生成的dynamicLib.dll文件拷贝到项目目录下,main.cpp代码如下

运行结果如下:

main.cpp代码分析:

语句typedef int (*lpAddFun)(int ,int )定义了一个与add函数接收参数类型和返回值均相同的函数指针类型,随后在main函数中定义了lpAddFun的实例addFun;

在函数main中定义了一个DLL HISTANCE句柄实例hDll,通过Win32API函数LoadLibrary 动态加载DLL模块并将DLL模块句柄赋给hDll;

在main函数中通过Win32API函数GetProcAddress得到所加载的DLL模块中函数add 的地址并赋值给addFun,经由函数指针addFun进行了对该DLL中add函数的调用;

在完成对dll的调用后,在main函数中通过Win32API函数FreeLibrary释放已加载的DLL模块。

通过以上的分析可知:

(a)DLL需要已某种特定的方式声明导出函数(或变量,类)

(b)应用程序需要以特定的方式调用DLL的淡出函数(或变量,类)

(2)、静态调用dll

1)、新建一个工程,命名为DllStaticCall,添加main.cpp文件,并将刚刚生成的DynamicLib.dll和DynamicLib.lib两个文件拷贝到工程目录下。

main.cpp代码如下

从上述代码可以看出,静态调用需要完成两个动作:

a)#pragma comment(lib,"DynamicLib.lib")是告诉编译器与该dll向对应的.lib文件所在的路径和文件名。

在生成dll文件时,连接器会自动为其生成一个对应的.lib文件,该文件包含了dll导出函数的符号名和序号(并没有实际的代码)。在应用程序中,.lib文件将作为dll的替代文件参与编译。

b)extern "C" int __declspec(dllimport) add(int a,int b)是声明导入函数。

静态调用不需要使用Win32API函数来加载和卸载Dll以及获取Dll中导出函数的地址,这是因为当通过惊呆连接方式编译生成程序时,应用程序中调用的与.lib文件中导出符号想匹配的函数符号将进入生成的exe文件中,.lib文件中包含的与之对应的dll文件的文件名也被编译存储在exe文件内部,当应用程序运行过程中需要加载dll文件时,windows将根据这些信息查找并加载dll,然后通过符号名实现对dll函数的动态链接,这样,exe将能直接通过函数名调用dll 的输出函数,就像调用程序内部的其他函数一样。

四、动态链接库def文件

上节介绍的dll导出函数是前面添加__declspec(impoet)语句,声明该函数为dll的导出函数,还有另一种方式声明函数为导出函数--通过def文件

1、如何使用def文件

(1)新建解决方案,添加两个项目,dllLib是生成dll文件的项目,dllcall是调用该dll

的项目。

(2)在dllLib中添加lib.cpp和dlllib.def两个文件,代码如下

Lib.cpp代码:声明两个函数,加法和减法

dllLib.def代码如下:

.def文件的规则为:

(1)LIBRARY语句说明该.def文件相对于的dll

(2)EXPORTS语句后面列出要到处的函数名称,可以在.def文件中的导出函数名后加@n,表示要导出函数的序号为n,在进行函数调用时,可以根据这个编号调用该函数

(3).def文件中的注释由每行开始处的分号(;)指定,且注释不能与语句共需一行。

由此可以看出,例子中的.def文件的含义是为生产名为DllLib的动态链接库,导出其中的add和sub函数,并且指定add函数序号为1,sub序号为2。

2、调用dll

调用的方法与刚刚介绍的一样,本例使用动态调用。将刚刚生成的dll拷贝到项目目录

main.cpp代码如下:

运行结果如下:

五、DllMain函数

Windows在加载dll时候,需要一个入口函数,就如同控制台需要main函数,win32成需需要WinMain函数一样,在前面的例子中dll并没有提供DllMain函数,应用程序也能成功的应用dll,这是因为windows在找不到DllMain函数时,系统会从其他运行库中引用一个不做任何操作的缺省DllMain函数版本,并不是意味着dll可以放弃DllMain函数,根据编写规范,windows必须查找并执行dll里面的DllMain函数作为加载dll的依据,它使得dll得益保留在内存里,这个甘薯不属于导出函数,而是dll的内部函数,这意味着不能直接在应用程序中引用DllMain函数,DllMain函数是自动被调用的。

1、为dll添加DllMain函数

(1)新建解决方案,添加两个工程。一个是生成dll,一个是调用dll。

Lib.h代码

Lib.cpp代码

Main.cpp代码

六、导出类

相关文档