2.动态链接库的生成和使用

1.什么是动态链接库

动态链接库(Dynamic-Link Library)通常包含程序员自定义的变量和函数,可以在运行时动态链接到可执行文件中

2.动态库扩展名

Windows下是.dll,Linux下是.so

3.Windows系统动态链接库

Windows操作系统核心有三个动态链接库(Kernel32.dll、User32.dll、Gdi32.dll),这些动态链接库构成了Win32 API函数

4.动态链接库的优点

1)节省内存和代码重用:当应用程序使用动态链接时,多个应用程序可以共享磁盘上单个DLL副本

2)可扩展性:DLL文件与EXE文件独立,只要接口不变,升级程序只需更新DLL文件不需要重新编译应用程序

3)复用性:DLL的编制与具体的编程语言以及编译器无关,不同语言编写的程序只要按照函数调用约定就可以调用同一个DLL函数

5.动态链接库的缺点

DLL地狱(DLL HELL)

6.创建动态链接库

1)创建DLL项目

2)添加.h头文件和.cpp文件

和静态库的写法一样

在.cpp中:

#include "func.h"
#include "stdafx.h"

int SquareSum(int a, int b)
{
	return (a*a + b * b);
}

int SumSquare(int a, int b)
{
	return ((a + b)*(a*b));
}

在.h文件中:

#pragma once

int SquareSum(int a, int b);

int SumSquare(int a, int b);

 这种情况下,我们点击生成,发现的确生成了一个.dll文件,但是没有.lib文件,如果我们用Dependency打开这个.dll文件,发现这个动态库是一个空文件,里面什么函数也没有

3)使用extern “C” 和_declspec(dllexport)

在.cpp里面的每个函数前面添加:

extern "C" _declspec(dllexport)

 完整的就是:

#include "func.h"
#include "stdafx.h"

extern "C" _declspec(dllexport) int SquareSum(int a, int b)
{
	return (a*a + b * b);
}

extern "C" _declspec(dllexport) int SumSquare(int a, int b)
{
	return ((a + b)*(a*b));
}

这样就生成了.lib文件和.dll两个文件

自己在VS2017中测试只在函数实现的地方加了 extern "C" 和_declspec(dllexport),并没有在函数声明的地方添加它,得到了两个文件;也测试了在函数实现和声明的地方都添加它,得到了两个文件;但如果只在函数声明的地方添加它而不在函数实现的地方添加,这样便还是只得到了.dll文件而没有.lib文件

4)生成.lib和.dll文件

7.使用动态链接库

1)创建一个应用程序项目

2)编写程序在.cpp中:

#include <iostream>
using namespace std;
#include "func.h"

#pragma comment(lib,"DynamicLib32.lib")

int main()
{
	int a = 34;
	int b = 32;
	cout << SquareSum(a, b) << endl;
	cout << SumSquare(a, b) << endl;

	system("pause");
	return 0;
}

.h中(.h文件可以从生成dll项目中拷贝过来,但需要注意下面几点):

#pragma once

int SquareSum(int a, int b);

int SumSquare(int a, int b);

如果在.h中直接这样,便会编译错误:

处理办法,在函数声明的地方加上extern “C”

#pragma once

extern "C" int SquareSum(int a, int b);

extern "C" int SumSquare(int a, int b);

但是这样方法也不是最好的,建议加上_declspec(dllimport),虽然它可以省略,但它可以提示编译器这个函数是从外部dll中导入的,有利程序的编译:

#pragma once

extern "C" _declspec(dllimport) int SquareSum(int a, int b);

extern "C" _declspec(dllimport) int SumSquare(int a, int b);

如果是从dll项目中直接拷贝过来的.h头文件中是:extern "C" _declspec(dllexport),发现也会编译正确,但不建议这样,建议改成上面的形式,把export改成import

3)添加.lib文件,dll项目不仅会生成.dll文件也会生成一个“配套”的.lib文件,简单理解,这个文件记录了dll中函数的入口地址,所以要像静态库中的.lib文件一样,用同样的两种方式把它加到我们的项目中,具体方法看静态链接库的生成和使用

添加好后,直接运行会得到错误:

4)添加.dll文件。把.dll文件添加到项目的.exe同一个路径下

这时运行便会得到正确结果:

8.注意

1)可以修改.lib文件的文件名,只要在项目引用它时,使用它目前的名称,便可以正确运行,但不能改变.dll文件的名字,不然也会出现找不到.dll文件的错误

2).dll文件必须和.exe放在一起,.exe文件在哪里.dll文件也得在那里,两者“共存亡”,否则就会出现找不到.dll文件的错误

3)和静态库一样,.dll文件也要和应用程序的位数相对应,要么都是64位的,要么都是32位的,不可交叉使用,否则出现:

猜你喜欢

转载自blog.csdn.net/qq_33757398/article/details/81545966
今日推荐