1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > Windows下动态链接库和静态链接库的生成以及调用

Windows下动态链接库和静态链接库的生成以及调用

时间:2021-11-15 18:49:23

相关推荐

Windows下动态链接库和静态链接库的生成以及调用

Windows下静态库和动态库的生成和调用

一、简介二、生成静态链接库(.lib)和动态链接库(.dll)三、静态链接库的调用四、动态链接库的调用动态链接库的两种调用方式仅使用.dll文件使用.h+.dll+.lib文件

一、简介

为了提高代码的复用性,引入了库,库是一段可执行代码的二进制形式,可以被操作系统直接载入内存使用。一般分为动态库和静态库,在Windows操作系统中静态库是以 .lib 为后缀的文件,动态库是以 .dll 为后缀的文件。

C++程序编译以及调用库的过程如下:

可以看到库是在链接过程和目标文件一起打包最终生成可执行文件,另外可以看到静态库和动态库是编译型语言所特有的,对于非编译型语言例如python,在实现上有所不同。

以下是静态链接库和动态链接库的区别:

1. 静态链接库(.lib):在链接阶段,会将汇编生成的目标文件.o与引用到的库一起链接打包到可执行文件中,相当于在可执行文件中每个用到库的地方,都会插入一份库的代码,这样会增加最终生成的可执行文件的体积。

2. 动态链接库(.dll):在链接阶段,动态库并不会被插入到目标文件.o中,而是在.exe可执行文件运行时才会被加载到内存,然后被程序调用,这样能大大减小生成的可执行文件的体积,并且动态链接库被修改时,并不需要重新编译生成源代码。

二、生成静态链接库(.lib)和动态链接库(.dll)

首先使用vs新建空项目,命名选择存储位置。

在项目中新建空白 .h 头文件和 .cpp 源文件,如下:

.h 头文件输入以下代码:

// addnum.h#ifndef __ADDNUM_H__#define __ADDNUM_H__extern "C" {_declspec(dllexport) int AddTwoInt(int a, int b);}#endif // !__ADDNUM_H__

.cpp 源文件输入以下代码:

// addnum.cpp#include "addnum.h"int AddTwoInt(int a, int b){return a + b;}

其中.h 头文件中extern “C” 表示使用C语言方式生成链接库,而_declspec(dllexport)用于声明库函数,.cpp源文件是该函数的具体实现过程,AddTwoInt()函数的功能是计算两个整形数之和。

点击项目->属性->常规->配置类型,设置当前项目的生成类型。如下图:

可以看到,这里可以选择生成的类型,如果要生成静态链接库,选择静态库,如果要生成动态链接库,选择动态库,选择之后点击确定即可。

点击生成,生成解决方案,然后就会在相应文件夹下生成库文件,如下:

生成静态库(.lib)

生成动态库(.dll)

生成了对应的动态库和静态库之后,下面就可以编写源程序来调用库。

三、静态链接库的调用

相较于动态链接库,静态链接库的调用相对简单,我们只需要在调用函数中声明好静态库中的函数接口,即可完成调用。

首先还是使用vs新建一个空项目,然后在项目下新建 addnum.h 和 main.cpp 文件,其中addnum.h 文件是对库的函数接口的说明,main.cpp 调用库函数。代码分别为: addnum.h文件:

// addnum.h#ifndef __ADDNUM_H__#define __ADDNUM_H__extern "C" {_declspec(dllimport) int AddTwoInt(int a, int b);}#endif // !__ADDNUM_H__

main.cpp文件:

// main.cpp#include <iostream>#include "addnum.h"using namespace std;int main() {cout << AddTwoInt(7, 19) << endl;return 1;}

addnum.h文件主要声明AddTwoInt()函数是从外部库导入的,main()函数调用AddTwoInt()函数计算"7+19"的结果。 将之前生成的libtest.lib静态链接库添加到项目的资源文件,完成后如下:

按Ctrl+F5或者点击调试->开始执行,运行源代码,得到结果如下:

可以看到程序返回结果为26,说明调用成功。

四、动态链接库的调用

动态链接库的两种调用方式

相对于调用静态库,调用动态库的过程更加复杂。主要由两种方法:

第一种方法是仅使用之前编译生成的.dll动态链接库文件,程序在运行时将库直接加载到内存中,获取函数的入口地址,然后利用函数指针直接调用。第二种方法是使用编译动态库过程中产生的静态库,这个静态库是系统自动生成的,其内部并不包含函数接口,作用只是获得动态库的函数地址,使得可以像调用静态库一样调用动态库。

仅使用.dll文件

同样的,首先新建一个空项目,在项目中新建一个.cpp源文件以及将之前生成的.dll动态库文件添加到项目文件夹下以及项目中,如下:

main.cpp中的代码:

// main.cpp#include <iostream>#include <Windows.h>using namespace std;typedef int (*pAddTwoInt)(int, int);//对应的函数指针类型,指向AddTwoInt()函数在内存中的入口地址int main(){HMODULE hdll; //动态链接库的句柄hdll = LoadLibrary("libtest.dll"); //加载动态链接库,返回其句柄if (hdll == NULL){cout << "lib load failed!" << endl;return 1;}pAddTwoInt fAddTwoInt = (pAddTwoInt)GetProcAddress(hdll, "AddTwoInt"); //获取动态链接库中AddTwoInt()函数的入口地址cout << fAddTwoInt(7, 19) << endl; //调用获取到的函数计算结果FreeLibrary(hdll);//调用结束,在内存中释放动态库return 1;}

运行,得到结果如下:

使用.h+.dll+.lib文件

这种方法调用需要使用编译生成动态链接库时自动生成的静态库,调用方法类似调用静态库,但是本质上却是使用的动态库。

同样的,首先新建一个空项目,在项目下添加addnum.h和main.cpp文件,然后将生成的动态库和静态库都复制到项目文件夹下,以及添加到项目,如下:

由于这里调用动态库的方法和调用静态库一样,因此此处addnum.h和main.cpp的内容页数一样的,如下: addnum.h文件:

// addnum.h#ifndef __ADDNUM_H__#define __ADDNUM_H__extern "C" {_declspec(dllexport) int AddTwoInt(int a, int b);}#endif // !__ADDNUM_H__

main.cpp文件:

// main.cpp#include <iostream>#include "addnum.h"using namespace std;int main(){cout << AddTwoInt(7, 19) << endl;return 1;}

运行,结果如下:

也成功的得到了结果。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。