封装DLL—生成具有导出项的动态链接库
具有导出项的意思是同时生成dll和lib文件,lib文件提供函数的入口,dll包含函数的内容和地址。通过这样的方式可以将自己的代码封装起来供别人使用。如在vs中可以添加附加依赖项将lib添加到项目中,在项目中包含头文件,编译执行即可。(例如在学习cv领域的opencv时需要配置的过程基本一致)
1 环境
Windows11+vs2017(win7以上和vs2015以上的系列方法大致相似)
2 新建vs项目
打开vs,选择“具有可导出项的动态链接库”,在下方输入名称,这个名称也是头文件的名称。例如封装的是一个具有四则运算方法的类,那么名称起为CaculateNum。
点击“确定”即可生成项目,需要做的就是在CaculateNum.h文件中声明类和方法,在.cpp文件中实现这些类的接口。
在.h文件中自动根据项目名称生成了类名,以及自动生成的一个变量和函数示例。其中类名可修改、变量和函数可以删除。
了解之后可以实现自己的类。实现如下:为了增加鲁棒和可读性添加了命名空间和模板方法以及示例。
.h文件的修改如下:
.cpp的修改如下:在.cpp中实现类的方法。
文章末尾给出.h以及.cpp的代码。
3 编译生成lib和dll
在写好代码之后,修改配置和发布平台,这里使用release x64,接着点击“生成”—“生成解决方案”,即可编译项目,
成功之后在文件项目的发布平台文件夹下中找到dll和lib文件并复制,
之后找到.h文件并复制。
4 在其他项目中使用
把复制的文件粘贴新建的工程里,
配置lib文件,
也可以添加头文件到项目中(或者在项目“属性”中添加包含目录),然后引用头文件,之后就可以正常使用了。
输出结果如下:
结尾
.h源码
// 下列 ifdef 块是创建使从 DLL 导出更简单的
// 宏的标准方法。此 DLL 中的所有文件都是用命令行上定义的 CACULATENUM_EXPORTS
// 符号编译的。在使用此 DLL 的
// 任何项目上不应定义此符号。这样,源文件中包含此文件的任何其他项目都会将
// CACULATENUM_API 函数视为是从 DLL 导入的,而此 DLL 则将用此宏定义的
// 符号视为是被导出的。
#ifdef CACULATENUM_EXPORTS
#define CACULATENUM_API __declspec(dllexport)
#else
#define CACULATENUM_API __declspec(dllimport)
#endif
//可以添加命名空间
namespace Caculating {
// 此类是从 dll 导出的
class CACULATENUM_API CaculateNum {
public:
CaculateNum(void);
// TODO: 在此处添加方法。
template<typename ADD>
ADD add(ADD a, ADD b);
template<typename SUB>
SUB sub(SUB a, SUB b);
};
}
.cpp源码
// CaculateNum.cpp : 定义 DLL 的导出函数。
#include "pch.h"
#include "framework.h"
#include "CaculateNum.h"
namespace Caculating {
// 这是已导出类的构造函数。
CaculateNum::CaculateNum()
{
return;
}
template<typename ADD>
ADD CaculateNum::add(ADD a, ADD b) {
return a + b;
}
template<typename SUB>
SUB CaculateNum::sub(SUB a, SUB b) {
return a - b;
}
}
template CACULATENUM_API int Caculating::CaculateNum::add(int a, int b);
template CACULATENUM_API float Caculating::CaculateNum::add(float a, float b);
template CACULATENUM_API double Caculating::CaculateNum::add(double a, double b);
template CACULATENUM_API int Caculating::CaculateNum::sub(int a, int b);
template CACULATENUM_API float Caculating::CaculateNum::sub(float a, float b);
template CACULATENUM_API double Caculating::CaculateNum::sub(double a, double b);