文章目录
说明
看滴水的视频写学习笔记总结
语言:c/c++
编译环境:vc++6.0
动态链接库方便我们封装函数,写大型项目的时候很重要,降低耦合,达到模块化的设计,方便重复使用与更新。
一、静态链接库
1.建立
新建一个静态链接库的项目,选好后,后面的全部点确定即可。
再新建一个类。
然后在添加自己的函数
然后按f7编译即可,在debug文件夹里生成.lib文件。
2.使用
(1).方式一
将先前生成的xxx.h文件和xxx.lib文件一并拖入我们要是用的项目文件中
在需要使用的项目中包含.h文件:#include”xxx.h”
在需要使用的项目中包含.lib文件:#pragma comment(lib,”xxx.lib”)
注意.cpp文件生成的.lib文件要同样的.cpp文件才能引用,.c文件无法引用
(2).方式二
将 xxx.h 和 xxx.lib 复制到要使用的项目中
在要使用的项目中包含:#include”xxx.h”
3汇编层,lib的调用
虽然我们这里没用写Plus的,但是可以步入查看这个函数的。
按f11步入。
就像我们的printf,也是一个函数,只不过是由C语言自身封装的,也可以步入函数查看。
3.静态链接库的特点
用OD打开刚才调用静态链接库的exe程序
换句话说,使用静态链接库生成的exe文件,可以不必和lib文件在同一文件夹
- 静态链接库里的代码实际上在程序调用后,编译是就嵌入了该程序。
- 使用静态链接生成的可执行文件体积较大,造成浪费
- 我们常用的printf、memcpy、strcpy等这些函数就来自这种静态库
二、动态链接库
1.建立
新建一个动态链接库的项目。
之后,我选A simple DLL project (只加一个入口的动态链接库)
然后新建一个类
建立之后,即可在新建的xxx.cpp中添加代码。
在xxx.h中声明添加的函数,这一点有差别
。
extern “C” -declspec(dllexport) int Plus (int x , int y)
名称 | 意义 |
---|---|
extern | 表示这是个全局函数,可以供各个其他的函数调用; |
“C” | 按照C语言的方式进行编译、链接 |
__declspec(dllexport) | 告诉编译器此函数为导出函数; |
然后按f7编译,即可在debug文件夹中生成xxx.dll文件和xxx.lib文件
2.使用
我们生成的动态链接库,xxx.dll文件里装的是代码,而xxx.lib里面装是代码在哪个位置。
(1).方式一:隐身链接
- 步骤1:将 xxx.dll文件和xxx.lib放到工程目录下面
-
步骤2:将 #pragma comment(lib,“DLL名.lib”) 添加到调用文件
-
步骤3:加入函数的声明
extern “C” __declspec(dllimport) __stdcall int Plus (int x,int y);
名称 | 意义 |
---|---|
__declspec(dllimport) | 告诉编译器此函数为导入函数; |
完成上述三个步骤即可成功调用动态链接库
(2).方式二:显示链接
-
步骤1:定义函数指针 , 即定义一种指向函数的指针
typedef int ( *lpPlus )(int , int ); typedef int ( *lpSub )(int , int ); typedef int ( *lpMul )(int , int ); typedef int ( *lpDiv )(int , int );
-
步骤2: 声明指针变量
lpPlus myPlus; lpSub mySub; lpMul myMul; lpDiv myDiv;
-
步骤3: 动态加载dll到内存中,将动态链接库加载到当前空间。
HINSTANCE hModule = LoadLibrary("xxx.dll") //HINSTANCE是指句柄,代表程序载入的模块,载win32下和HMODULE相同
-
步骤4: 调用API函数获取动态链接库里的函数地址
//函数名原来是什么,引号里就写什么,因为我们导出函数后别人根据函数名寻找。 myPlus = (lpPlus)GetProcAddress(hModule , "Plus"); mySbu = (lpSub)GetProcAddress(hModule , "Sub"); myMul = (lpMul)GetProcAddress(hModule , "Mul"); myDiv = (lpDiv)GetProcAddress(hModule , "Div");
-
步骤5: 通过函数指针调用函数
int a = myPlus(10,2);
具体流程如下图,跟着标号1、2、3、4、5、6。
完成显示链接。
特别说明,对应的句柄
Handle 是代表系统的内核对象,如文件句柄,线程句柄,进程句柄
HINSTANCE 在win32下与HMODULE是相同的东一
HWND 是窗口句柄
以上的都是一个无符号整形数据
(3).动态链接库的特点
我们还是用OD打开刚才调用动态链接库的exe程序
再查看我们代码的反汇编地址,下断点,进入到调用库的函数的地址
也就是说,我们只需更改动态链接库里的函数内容,即可对调用这个库的程序进行更改,而不用更新整个程序
所以动态链接库才是方便更改,且空间小。
真正实现模块化。
实现高类聚低耦合。
三、使用.def文件导出动态链接库
通过使用.def文件导出动态链接库,可以选择性的隐藏动态链接库里的函数的名字,起到隐藏名字的作用,防止别人通过获取函数名而获取信息。
建立过程
开始和动态链接库的建立方式一样,新建一个类,名字为“TestDll”
声明函数就是直接声明
- 不同点是:新建一个
文本文件
,取名xxx.def
EXPORTS
Plus @12
Sub @15 NONAME
Mul @13
Div @16
然后按f7即可编译生成.dll文件。
查看该dll文件
我们用vc++6.0的工具DEPENDS
打开刚才生成的dll查看他内部函数
打开后
调用该dll文件
直接写函数名字
虽然函数名被隐藏了,但不管事隐式链接还是显示链接,都可以像原来一样直接通过写函数名字调用
通过写函数序号
不管有没有被隐藏函数名,都可以在显示链接时通过写函数序号调用该函数,不过记得将数字强转为char*
类型
成的dll查看他内部函数
——————————————————————
欢迎大家留言评论交流^ _ ^