本文主要参考了这篇博文
本文介绍了vs封装类的dll的方法,经过本人实测可以跑通
PS:之前的博文提到的问题“这两种方法都是 dll 封装函数的,没有找到 dll封装类的;需要封装类的场景很少吗,求问?” 结合本文正好可以作为对比。
———————————————————————————————————————————
PS2:C++接口封装及DLL中使用头文件实例_一行一生-CSDN博客_c++ dll 头文件
这篇文章写出了我看到的第三种方法,但是没看到他的文件结构和设置操作,看不太明白,暂时先贴在这里吧,稍后看一看
—————————————————————————————————分割线———————
核心思想:dll把实现封装起来,对外提供一个接口,这个接口就是基类的纯虚函数
具体步骤:
1、创建DLL项目,命名根据实际需求,这里命名为AddDll
项目自动生成了pch.cpp,pch.h,dllmain.cpp,framework.h四个文件,这个先不管它,也不要删除。
2、需要封装的部分。本文是BP.cpp和BP.h,BP.cpp主类为 class TEST,主要结构如下:
BP.h内容:
#include "pch.h"
#pragma once
/*BP.h*/
class TEST: public BPBase
{
public:
int count = 0;
public:
TEST();
~TEST();
bool add(int num1, int num2, int result);
};
BP.cpp内容:
/*BP.cpp*/
#include "pch.h"
#include "BP.h"
TEST::TEST() {}
TEST::~TEST() {}
bool TEST::add(int num1, int num2, int result)//不想让用户看见这个函数
{
result = num1 + num2;
return true;
}
3、基类
因为我们封装dll是不想让用户看见我们的源码细节,只需要提供个接口给他们调用,所以我们建个虚基类,基类中的函数就是函数调用的接口。
我将基类写在pch.h文件中,不用写函数的实现,只写声明就可以了。
// pch.h: 这是预编译标头文件。
// 下方列出的文件仅编译一次,提高了将来生成的生成性能。
// 这还将影响 IntelliSense 性能,包括代码完成和许多代码浏览功能。
// 但是,如果此处列出的文件中的任何一个在生成之间有更新,它们全部都将被重新编译。
// 请勿在此处添加要频繁更新的文件,这将使得性能优势无效。
#ifndef PCH_H
#define PCH_H
// 添加要在此处预编译的标头
#include "framework.h"
#define CLASS_DECLSPEC __declspec(dllexport)
/*pch.h*/
class BPBase
{
public:
BPBase() {};
virtual ~BPBase() {};
public:
//只开放一个函数接口
virtual bool add(int num1, int num2, int result) = 0;
};
#endif //PCH_H
导出类和函数,在基类所在头文件中加上这一句
#define CLASS_DECLSPEC __declspec(dllexport)//表示这里要把类导出再修改基类声明,所有类都要加上CLASS_DECLSPEC
4、工厂类
因为基类是虚类,不能创建实例,所以用基类的指针指向子类,调用子类的功能。创建BPFactory.cpp和BPFactory.h,联系基类和子类。
/*BPFactory.h*/
#include"pch.h"
#pragma once
class CLASS_DECLSPEC BPFactory
{
public:
BPFactory();
~BPFactory();
public:
BPBase* CreateObject();
void DeleteObject(BPBase* _bp);
};
/*BPFactory.cpp*/
#include "pch.h"
#include"BPFactory.h"
#include "BP.h"
// 当使用预编译的头时,需要使用此源文件,编译才能成功。
BPFactory::BPFactory()
{}
BPFactory::~BPFactory()
{}
BPBase* BPFactory::CreateObject()
{
return new TEST;
}
void BPFactory::DeleteObject(BPBase* _bp)
{
if (_bp)
delete _bp;
}
5、生成dll和lib文档
选择debug或release,两个都可以生成dll和lib,选择哪个就可以去项目下的哪个文件下找dll和lib,具体区别可以自己查,X86和X64都可以选择,最后点击调试,就可以了。
6、DLL调用
重新创建一个项目TestAddDll,将原来DLL项目的dll和lib还有基类头文件pch.h和工厂类BPFactory.h,共四个文档复制到新项目里,如下图红圈标注的四个文件
新项目的 main 函数
#include <iostream>
#include "BPFactory.h"//工厂类调用
using namespace std;
int main()
{
BPFactory factory;
BPBase* AddDll = factory.CreateObject();
int num1 = 10;
int num2 = 20;
int result = 0;
if (AddDll->add(num1, num2, result))
{
cout << num1 << "+" << num2 << "=" << num1 + num2 << endl;
}
else
{
cout << "error occured" << endl;
}
}
添加包含目录
在这里我把前面 AddDLL 的 pch.h 所在的目录添进来了
添加依赖
最后结果: