代码分发方式
动态库与静态库唯一的区别就是动态库多了个dll文件
库的作用
- 代码解耦、重用
- 对外提供服务(export)
- 典型应用:exe调用dll。我们打开软件目录一堆dll,少量exe就是这个道理
对于小软件,它会把代码都写到exe里面,但是大软件代码是需要重用的。
以火绒安全为例:
库的分类(形式)
-
静态库:与exe打包成exe(一个文件),windows就是.lib文件
linux就是.a文件
它们在调用时会与它们的调用者.exe打包成一个.exe
【其实windows会变成pe可执行文件,linux是.elf可执行文件,这里为了方便理解这么说】
-
动态链接库(共享库)
与exe是独立的2个文件
windows就是.dll文件
linux就是.so文件
动态库就是当你调用dll文件的时候,别人也可以调用,也就是说是可以重用的,而静态库是不可以的。
静态库与动态库的区别
-
静态库
1、优点:代码合并到模块中,无零散文件。
2、缺点:模块体积变大,当多个模块使用该库时,内存中有多份代码。
-
动态库
1、优点:模块体积几乎不变,当多个模块使用该库时,内存中只存在一份代码。
2、缺点:代码在单独文件中,有零散文件。
总结:
静态库的代码有改动时,所有依赖它的文件都要重新编译。动态库不用(某些更改),可以只更新动态库文件(.dll文件)。
C/C++到可执行程序的过程
静态库配置方法
首先我们编译好了一份静态库文件,只有.h文件和.lib文件
lib文件使用方式有两种,第一种是最简单的,一般自己做练习的时候使用比较好,但是如果这样配置库的话并不会很方便,它会使你的代码显得杂乱。
第一种:
通过代码
#include ".h文件绝对路径"
,然后通过
#pragma comment(lib,"lib文件绝对路径")
来引用lib文件
StabicLib.h代码:(返回两个数之和)
#pragma once
int Add(int a,int b)
主程序代码:
#include <windows.h>
#include <iostream>
#include ".h文件绝对路径"
#pragma comment(lib,"lib文件绝对路径")
using namespace std;
int main()
{
cout << Add(1,1) << endl;
return 0;
}
运行结果:(返回值2)
第二种:【推荐】
我们点击项目->属性,然后步骤如下
我们在这里写下头文件的目录(只需写到文件夹路径,不需写到文件路径)
然后头文件就配置好了
接下来是lib文件,lib文件是给链接器看的,我们需要配置它的目录
同理,在这里填上lib文件夹路径
然后还需要在输入->附加依赖项中写上lib文件的名字
这样就配置好了,但是需要注意这里的配置是要和项目配合使用的
Debug配Debug,X86配Win32
然后接下来我们就可以像正常使用别的库一样,使用它
代码:
#include <windows.h>
#include <iostream>
#include <StaticLib.h>
using namespace std;
int main()
{
cout << Add(1,1) << endl;
return 0;
}
然后就可以正常运行了
动态库配置方法
主体流程基本差不多,只是多了个dll文件的配置
可以看到这里有三个文件
.h文件和.lib文件与静态相同这里就不再演示【Dll.dll文件我们不需要配置】
我们需要注意要把dll文件复制到项目编译后的项目文件夹里
#include <windows.h>
#include <iostream>
#include <Dll.h>
using namespace std;
int main()
{
cout << Add(1,1) << endl;
return 0;
}
运行:
注意:
动态库的特点是需要dll文件与exe文件在一起或者是在一些特定的dll搜索路径下即可。
衍生技术
黑客hook dll:代码替换或叫代码劫持
就是说本来你这个程序是调用一个什么什么dll里面的一个什么什么函数来实现一个什么什么功能,黑客通过分析你的PE格式或者elf格式发现了,然后就写了一个dll格式的文件,里面也准备了一个什么什么函数,然后替换你原来里面的dll文件|so文件,然后你调用的时候执行的就是黑客准备好的代码,这个就叫做代码劫持。