一、Visual Studio 2022 创建动态链接库
1. 点击创建新项目
选择【动态链接库(DLL)】或【MFC动态链接库】
选哪个都行,根据你自己的需求来,在学习动态链接库这块这里并不是重点,所以没有区别
这里我选择的是【MFC动态链接库】
2. 点击下一步后,配置项目名称和解决方案名称,然后点击创建即可
3. 在头文件和源文件文件夹下分别创建mydll.h
和mydll.cpp
4. mydll.h
代码为:
#ifdef BUILD_MYDLL
#define API_SYMBOL __declspec(dllexport)
#else
#define API_SYMBOL __declspec(dllimport)
#endif // BUILD_MYDLL
extern "C" API_SYMBOL int add_array(int* data, int len);
解释一下:
__declspec(dllexport)
关键字从 DLL 中导出数据、函数、类或类成员函数
__declspec(dllimport)
关键字可以将函数导入应用程序、访问导出的 DLL 数据
更加详尽的用法解释请参考官方文档:导入和导出
extern "C"
指定函数在别处定义并使用 C 语言调用约定。
更加详尽的用法解释请参考官方文档:extern (C++)
第一段代码意为:
如果我们定义了名为BUILD_MYDLL
的宏,那么就将__declspec(dllexport)
重命名为API_SYMBOL
如果我们没有定义了名为BUILD_MYDLL
的宏,那么就将__declspec(dllimport)
重命名为API_SYMBOL
将我们定义的函数add_array
按照C语言的方式进行编译和连接,并从DLL中导出
5. mydll.cpp
代码为:
#include"pch.h"
#include "mydll.h"
#define BUILD_MYDLL
#include <iostream>
using namespace std;
int add_array(int* data, int len)
{
for (int i = 0; i < len; i++) {
cout << data[i] << ",";
}
cout << endl;
int nTotal = 0;
for (int i = 0; i < len; i++) {
nTotal += data[i];
}
return nTotal;
}
#define BUILD_MYDLL
这句定义了一个名为BUILD_MYDLL
的宏,所以mydll.h
中的#ifdef BUILD_MYDLL
这句的条件成立。
下面定义了一个名为add_array
的函数,实现了输出数组元素,计算所有数组元素之和的操作。
6. 生成dll
然后我们鼠标放在项目目录,右键,点击生成
可以看到我们成功的生成了三个文件
到这里我们的动态链接库就生成好了
二、创建应用程序隐式调用动态库
1. 创建控制台程序
在【解决方案】处右键,选择【添加】,选择【创建项目】
选择【控制台应用】,配置【项目名称】,点击【创建】
2. 在主程序中引入头文件
#include <mydll.h>
这里会显示无法找到mydll.h
我们在项目处右键,选择属性
选择【C/C++】 -> 【常规】 -> 【附加包含目录】 -> 【小箭头】-> 【编辑】
如图接着点:
选择上一级目录
选择动态库所在的目录
然后点击确定返回,应用,确定。
3. 引入lib符号文件
还是打开【属性】,按照如下图顺序进行编辑
输入我们之前生成好的lib文件的名称,然后点击确定
再为lib添加搜索路径,按照下图点击编辑
我们可以先打开资源管理器确认一下,确认我们需要的DemoDll.lib
文件的位置,然后再回到VS中选择DemoDll.lib
所在的目录
确认好了选择这个debug文件夹,然后点击【选择文件夹】,【确定】,【应用】,【确定】
4. 编写调用代码
#include <iostream>
#include "mydll.h"
int main()
{
int arr[] = { 3,6,7,8 };
int nLen = sizeof(arr) / sizeof(int);
int nTotal = add_array(arr, nLen);
std::cout << "数组元素求和结果:" << nTotal << std::endl;
}
5. 启动项目
在项目处【右键】,【设为启动项目】,然后【运行】
6. 运行结果
可以看到我们成功的调用到了静态库中的函数
三、创建应用程序显式调用动态库
1.创建控制台程序
和上方创建控制台应用程序类似
在【解决方案】处右键,选择【添加】,选择【创建项目】
选择【控制台应用】,配置【项目名称】,点击【创建】
不多赘述
2. 编写程序
第一步,创建一个别名,他引用的函数类型需要和dll中的导出函数一致;
第二步,加载mydll.dll 动态库文件
第三步,获取动态库中的函数地址,如果获取成功就第四步
第四步,调用函数
第五步,释放动态库句柄
#include <iostream>
#include<Windows.h>
// 第一步,创建一个别名,他引用的函数类型需要和dll中的导出函数一致
typedef int (*LPDO_ARRAY)(int* pArr, int nLen);
int main()
{
HINSTANCE hDll; // 定义一个句柄,引用动态库
LPDO_ARRAY lpDo_array; // 定义一个函数指针,用来指向导出函数
// 第二步,加载MFCLibrary.dll 动态库文件
hDll = LoadLibrary(L"DemoDll.dll");
if (hDll != NULL) {
// 第三步,获取动态库中的函数地址
lpDo_array = (LPDO_ARRAY)GetProcAddress(hDll, "add_array");
if (lpDo_array != NULL) {
// 第四步,调用函数
int nArr[] = { 1,2,4,6 };
int nLen = sizeof(nArr) / sizeof(int);
int nRet;
// 通过函数指针lpDo_array调用函数
nRet = lpDo_array(nArr, nLen);
std::cout << "返回值:" << nRet << std::endl;
}
// 第五步,释放动态库句柄
FreeLibrary(hDll);
}
}
3. 启动项目
在项目处【右键】,【设为启动项目】,然后【运行】