C 和 C++ 中动态链接库的创建和链接
1. 创建 DLL(动态链接库)-C++ 方式
1. 创建 DLL(动态链接库 - C++ 方式)
1. 在 VS(以 VS2017 为例) 中创建 DLL 动态链接库.
解决方案名称为: MyDLL
项目名称为: Dll1
2. 创建头文件 Dll1.h
输入如下代码:
- #pragma once
- #ifdef MY_DLL_EXP
- #else
- #define MY_DLL_EXP _declspec(dllimport)//// 当编译时, 头文件不参加编译, 所以. cpp 文件中先定义, 后头文件被包含进来, 因此外部使用时, 为 dllexport, 而在内部编译时, 则为 dllimport
- #endif
- // 创建一个常量
- MY_DLL_EXP extern const double PI;
- // 创建一个测试用的函数
- void MY_DLL_EXP Hello();
- // 创建一个测试用的类
- class MY_DLL_EXP Calculate {
- public:
- double add(double a, double b);
- double sub(double a, double b);
- double mult(double a, double b);
- double divd(double a, double b);
- };
3. 创建 Dll1.cpp(如存在则不用创建)
输入如下代码:
- #include "stdafx.h"
- #include "Dll1.h"
- // 注意以上两个头文件的相对顺序不能改变
- #include <iostream>
- #define MY_DLL_EXP _declspec(dllexport)
- // 导出常量
- const double PI = 3.14;
- // 导出函数
- void Hello() {
- std::cout <<"Hello World!" << std::endl;
- }
- // 导出类中的函数
- double Calculate::add(double a, double b) {
- return a + b;
- }
- double Calculate::sub(double a, double b) {
- return a - b;
- }
- double Calculate::mult(double a, double b) {
- return a * b;
- }
- double Calculate::divd(double a, double b) {
- if (b == 0)
- return 0;
- return a / b;
- }
4. 生成即可完成 C++ 版动态链接库的创建
注意: 动态链接库文件不能直接执行
2. 链接 DLL(动态链接库 - C++ 方式)
1. 隐式链接
1. 准备
- Dll1.h(Dll1 项目目录中)
- Dll1.lib(解决方案的 Debug 中)
- Dll1.dll(结局方案的 Debug 中)
2. 创建一个测试用隐式链接动态链接库的项目
此处以空项目为例
项目名称为: testDll1
此处为了方便, 将 Dll1.h,Dll1.lib,Dll1.dll 放入到新建的项目目录下.
3. 右击解决方案, 选择属性. 在通用属性中的启动项目中选择当前选中内容, 确认即可.
4. 右击要链接 DLL 的项目 testDll1, 选择属性, 进行配置.
(1) 配置属性 ->VC++ 目录 -> 在 "包含目录" 里添加头文件 Dll1.h 所在的目录
(2) 配置属性 ->VC++ 目录 -> 在 "库目录" 里添加头文件 Dll1.lib 所在的目录
(3) 配置属性 -> 链接器 -> 输入 -> 在 "附加依赖项" 里添加 Dll1.lib(若有多个 lib 则以空格隔开)
4. 将 Dll1.dll 文件放入到创建的项目的目录下或是解决方案的 Debug 目录下
5. 创建 testDll1.cpp
输入如下测试代码:
- #include "Dll1.h"
- #include <iostream>
- // 隐式调用 DLL
- using namespace std;
- int main() {
- cout <<PI << endl;// 测试输出常量
- Hello();// 测试函数
- // 测试类
- Calculate calc;
- cout << "3 + 2 =" << calc.add(3, 2) << endl;
- cout << "4 - 1 =" << calc.sub(4, 1) << endl;
- cout << "3 * 2 =" << calc.mult(3, 2) << endl;
- cout << "4 / 2 =" << calc.divd(4, 2) << endl;
- cin.get();// 暂停
- }
输出结果:
2. 显式链接
显示链接可以在执行过程中随时加载 DLL 文件, 也可以随时卸载 DLL 文件, 这是隐式链接所无法作到的, 所以显式链接具有更好的灵活性, 对于解释性语言更为合适.
显示链接主要是使用 LoadLibrary() 函数. 此处只说明显示链接 DLL 的导出函数的使用方法, 导出类的使用比较复杂, 将在我的其他文章中说明.
1. 创建测试用空项目 testDll2
2. 将 Dll1.dll 放入到 testDll2 项目目录下
3. 创建 testDll2.cpp
输入如下代码:
- // 显示链接 DLL - 使用 GetProcAddress 获取函数的名字会有所改变需要使用 dumpbin.exe 查询
- #include <Windows.h>// 加载头文件
- #include <iostream>
- using namespace std;
- // 设置全局变量 hInst 用于存储 dll 句柄并加载动态链接库
- HINSTANCE hInst = nullptr;
- // 声明函数指针
- typedef void(*Hello)();
- int main() {
- // 加载动态链接库 D111.dll
- hInst = LoadLibrary("Dll1.dll");
- if (hInst == nullptr) {
- cout <<"动态链接库加载失败!!!" << endl;
- FreeLibrary(hInst);
- cin.get();
- return 0;
- }
- // 加载导出函数, 此处函数名有所不同, 需要使用 dumpbin.exe 进行查询
- Hello hello = (Hello)GetProcAddress(hInst, "?Hello@@YAXXZ");
- cout << "Hello()=";
- hello();
- cin.get();
- // 释放动态链接库
- FreeLibrary(hInst);
- return 0;
- }
4. 查询函数名称的方法
使用 dumpbin.exe 查询
打开 VS 的自带的本机工具命令提示
打开之后的界面:
进入 Dll1.dll 所在路径
在控制台中输入 dumpbin -exports Dll1.dll 进行查询
Hello 函数的函数名为? Hello@@YAXXZ
5. 生成并运行
运行结果
2. 创建 DLL(动态链接库 - C 方式)
1. 创建 DLL(动态链接库 - C 方式)
1. 创建动态链接库项目, 名称为 Dll2
2. 创建 Dll2.h
输入如下代码
- #pragma once
- #ifdef MY_DLL_EXP
- #else
- #define MY_DLL_EXP _declspec(dllimport)//// 当编译时, 头文件不参加编译, 所以. cpp 文件中先定义, 后头文件被包含进来, 因此外部使用时, 为 dllexport, 而在内部编译时, 则为 dllimport
- #endif
- // 导出函数 Add
- extern "C" MY_DLL_EXP double Add(double a, double b);
3. 创建 Dll2.cpp(如果有则不需要创建)
输入如下代码:
- #include "stdafx.h"
- #include "Dll2.h"
- // 注意以上两个头文件的相对顺序不能改变
- #define MY_DLL_EXP _declspec(dllexport)
- double Add(double a, double b) {
- return a + b;
- }
4. 生成即可.
2. 链接 DLL(动态链接库 - C 方式)
1. 隐式链接
1. 准备
- Dll2.dll(解决方案 Debug 目录下)
- Dll2.lib(解决方案 Debug 目录下)
2. 创建测试项目 testDll3
3. 把 Dll2.dll 和 Dll2.lib 放入到 testDll3 项目目录下
4. 创建 testDll3.cpp
输入如下代码:
- // 隐式调用
- #include <iostream>
- #pragma comment(lib,"Dll2.lib")
- using namespace std;
- // 载入函数, 此处起到头文件的作用
- extern "C" _declspec(dllimport) double Add(double a, double b);
- int main() {
- cout <<"Add(3,4)=" << Add(3, 4) << endl;
- cin.get();
- return 0;
- }
5. 生成并运行
运行结果:
2. 显式链接
1. 新建测试项目 testDll4
2. 把 Dll2.dll 放入新建的项目 testDll4 目录中
3. 新建 testDll4.cpp
创建 dll 过程中使用 C 编译器来编译函数, 这样 DLL 文件中的函数名和原 dll 工程中的函数名就一致了.
墙裂推荐此种方式
输入如下代码:
- // 显示链接 DLL-C
- #include <Windows.h>// 加载头文件
- #include <iostream>
- using namespace std;
- // 设置全局变量 hInst 用于存储 dll 句柄并加载动态链接库
- HINSTANCE hInst = nullptr;
- // 声明函数指针
- typedef double(*Add)(double a,double b);
- int main() {
- // 加载 Dll2.dll
- hInst = LoadLibrary("Dll2.dll");
- if (hInst == nullptr) {
- cout << "动态链接库加载失败!!!" << endl;
- FreeLibrary(hInst);
- cin.get();
- return 0;
- }
- // 加载函数
- Add add = (Add)GetProcAddress(hInst, "Add");
- cout << "Add(3,4)="<<add(3,4)<<endl;
- cin.get();
- FreeLibrary(hInst);
- return 0;
- }
4. 生成并运行.
来源: https://www.cnblogs.com/xiangjinpeng/p/10192888.html