VS2019 - 动态库的编写和调用
完善自己知识体系的一些内容:
用C++编写的DLL(动态链接库)中,导出类的接口封装方法总结
详解dll的封装,以及三种调用方法(将±×÷封装为例)
1 VS2019创建 dll 并隐式调用动态库
参考:BIliBili:Visual Studio 2019-编写C++动态链接库
下面仅对自己在调试过程中需要注意的点就行补充:
1.1 创建自己的dll工程,然后创建自己的头文件和源文件
参考:优快云:VS2019环境下C++动态链接库(DLL)的创建与调用
2.2 在头文件中声明自己的导出函数:
#pragma once
#ifndef BUILD_MYDLL
#define API_SYMBOL __declspec(dllexport)
#else
#define API_SYMBOL __declspec(dllimport)
#endif
extern"C" API_SYMBOL int convert_array(int* data, int len);
然后鼠标放在函数名称上,右键选择快速操作与重构,再选择在xxx.cpp中创建函数定义,最后对此cpp文件以及函数进行更改:
#include "pch.h"
#define BUILD_MYDLL
#include "mydll.h"
#include <iostream>
using namespace std;
int convert_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];
--data[i];
}
return nTotal;
}
此时就可以对项目进行生成。
1.3 创建应用程序隐式调用调用动态库(右键————>新建项目————>控制台应用)
新创建的应用程序采用隐式调用的方式来调用这个动态库,需要三个文件的支持(创建动态链接库的工程名:xxx):xxx.lib xxx.dll(【CSAPP-深入理解计算机系统】7-8. 动态链接共享库) 和 自己创建的头文件mydll.h
- 在项目的cpp文件和属性页中的附加包含目录中添加头文件:添加目录如下
- 引入 lib 和 搜索路径(lib符号文件所在目录)
Debug目录下:
- 编写调用代码
#include <iostream>
#include "mydll.h"
int main()
{
int arr[] = { 13, 6, 7, 8 };
int nLen = sizeof(arr) / sizeof(int);
int nTotal = convert_array(arr, nLen);
std::cout << "数组元素求和结果 : " << nTotal << std::endl;
std::cout << " 数组元素新值: " << std::endl;
for (int i = 0; i < nLen; i++) {
std::cout << arr[i] << ",";
}
}
现在就可以运行程序了。
2 显式调用C++动态库
上文展示了C++动态库的编写和隐式调用,下面展示C++动态库的显式调用,需要使用 2.1中的项目,新项目创建为控制台应用,创建过程参考上文,只需要dll的从动态库这一个文件就可以调用了
参考BiliBili:Visual Studio 2019-显式调用C++动态库
项目代码如下:
#include <iostream>
#include <Windows.h>
//第一步,创建一个别名,其引用的函数类型需要和dll中的导出函数一致
typedef int (*LPDO_ARRAY)(int* pArr, int nlen);
int main()
{
HINSTANCE hDLL; //定义一个实例句柄,引用动态库
LPDO_ARRAY lpDo_array;//定义一个函数指针用来指向导出函数
//第二步,加载testDLL.dll动态库文件
hDLL = LoadLibrary(L"testDLL.dll");
if (hDLL != NULL) {
//第三步, 获取动态库dll中的函数地址
lpDo_array = (LPDO_ARRAY)GetProcAddress(hDLL, "convert_array");
if (lpDo_array != NULL) {
//第四步,调用函数
int nArr[] = { 13, 6, 7, 8 };
int nlen = sizeof(nArr) / sizeof(int);
int nRet;
//通过函数指针lpDo_array调用函数
nRet = lpDo_array(nArr, nlen);
std::cout << "数组元素求和结果 : " << nRet << std::endl;
std::cout << " 数组元素新值: " << std::endl;
for (int i = 0; i < nlen; i++) {
std::cout << nArr[i] << ",";
}
}
//第五步, 释放动态库句柄
FreeLibrary(hDLL);
}
}
也可以直接把解决方案的Debug目录中的exe文件和dll文件放到同一个目录下直接执行如下: