一、动态库的特点
- 运行时独立存在
- 源码不会链接到执行程序
- 使用时加载(使用动态库必须使用动态库执行)
- 与静态库的比较:由于静态库是将代码嵌入到使用程序中,多个程序使用时,会有多份代码,所有代码体积会增大,动态库的代码只需要存在一份,其他程序通过函数地址使用,所以代码体积小;静态库发生变化后,新的代码需要重新链接嵌入到执行程序中,动态库发生变化后,如果库中函数的定义(或地址)未变化,其他使用DLL的程序不需要重新链接
二、动态库的创建
- 创建动态库项目
- 添加库程序
- 库程序导出:提供给使用者库中的函数等信息
1.声明导出
使用_declspec(dllexport)导出函数,注意:动态库编译连接后,也很会有LIB文件,是作为动态库函数映射使用,与静态库不完全相同。
库头文件:
#pragma once _declspec(dllexport) int CPPdll_add(int add1, int add2); _declspec(dllexport) int CPPdll_sub(int sub1, int sub2); _declspec(dllexport) int CPPdll_mul(int mul1, int mul2);
库源文件:
#include "dllmain.h"
int CPPdll_add(int add1, int add2) {
return add1 + add2;
}
int CPPdll_sub(int sub1, int sub2) {
return sub1 - sub2;
}
int CPPdll_mul(int mul1, int mul2) {
return mul1 * mul2;
}
2.模块定义文件.def
例如:LIBRARY DLLFunc(库),EXPORTS(库导出表),DLL_Mul @1(导出的函数)
三、动态库的使用

动态库中的lib文件存放着函数名称和每个函数的编号,当运行程序加载dll文件时,会根据lib文件中的编号去dll文件中找到对应的函数名称,从而找到对应的函数地址
1.隐式链接(操作系统负责动态库执行)
(1).头文件和函数原型:可以在函数原型的声明前,增加_declspec(dllimport)
(2).导入动态库的LIB文件
(3).在程序中使用函数
(4).隐式链接的情况,dll文件可以存放的路径:
- 与执行文件在同一个目录
- 当前工作目录
- Windows目录
- Windows/System32目录
- Windows/System
- 环境变量PATH指定目录
示例代码:
#include <iostream>
#include "../CPPDll/dllmain.h"
using namespace std;
//通过链接器到哪去抓取编号和dll文件名("CPPdll.dll")
#pragma comment(lib, "../Debug/CPPdll.lib")
int main() {
int sum = CPPdll_add(5, 4);
int sub = CPPdll_sub(5, 4);
int mul = CPPdll_mul(5, 4);
cout << "sum:" << sum << endl;
cout << "sub:" << sub << endl;
cout << "mul:" << mul << endl;
return 1;
}
2.显示链接(程序员自己负责动态库的执行)
(1).定义函数指针类型(typedef)
(2).加载动态库:
HMODULE LoadLibrary(
LPCTSTR lpFileName //动态库文件名或全路径
);返回DLL的示例句柄(HINSTANCE)
(3).获取函数地址:
FARPROC GetProcAddress(
HMODUKE hModule, //DLL句柄
LPCSTR lpPricName //函数名称
);成功返回函数地址
(4).使用函数
(5).卸载动态库
BOOL FreeLibrary(
HMODULE hModule //DLL的实例句柄
);