一个完整的项目应该是这样的图,有一个主程序,依赖其他的项目
这边以控制台主程序输出。以Debug x64为例,如果是release的话需要重新配置一下
第一步:
将项目配置改成Debugx64,这边Vs版本是2019,用C++17标准(右击项目属性)
右击解决方案-》添加-》新建项目-》创建动态链接库-》创建两个动态库topdll和lastdll
第二步:
添加项目之间的依赖关系,lastdll依赖topdll,completeProject依赖lastdll和topdll。
右击lastdll项目
右击completeProject项目
可以看到完整的生成顺序
将几个项目全部改成C++17,每个项目需要手动修改
点击生成解决方案,查看CompleteProject项目文件夹位置
第三步:
为dll项目设置导出宏,用来导出函数等等,编译器自己已经给了预处理器导出宏,当时太长了,我们可以改简单一点
现在测试的功能是:主程序存了同学的姓名、年龄、性别,将几个同学的信息存入单例,然后lastdll将单例信息提取出来,输出人数,主程序获取lastdll中的人数数据。其中主程序用到了topdll和lastdll,lastdll利用到了topdll,测试了全部功能。
给Topdll写文件,topdll写一个单例类,其中利用刚刚预处理器定义的TOPDLL来设置导出,TOPDLL主要作用是可以让编译器知道TOPDLL项目是导出,其他项目使用它都是导入
SingleInstance.h
#pragma once
#include <string>
#include <vector>
using namespace std;
#ifdef TOPDLL
#define TOPDLL_API _declspec(dllexport)
#else
#define TOPDLL_API _declspec(dllimport)
#endif
struct student
{
string name;
int age;
bool sex;
};
class TOPDLL_API SingleInstance
{
public:
static SingleInstance& GetInstance();
~SingleInstance();
SingleInstance(const SingleInstance&) = delete;
SingleInstance& operator=(const SingleInstance&) = delete;
private:
SingleInstance();
public:
void GetStudentsInfo(vector<student>& stu);
void SetStudentsInfo(const student& stu);
private:
vector<student> students;
};
SingleInstance.cpp
#include "pch.h"
#include "SingleInstance.h"
SingleInstance& SingleInstance::GetInstance()
{
static SingleInstance m_instance;
return m_instance;
}
SingleInstance::SingleInstance()
{
}
SingleInstance::~SingleInstance()
{
}
void SingleInstance::GetStudentsInfo(vector<student>& stu)
{
stu = students;
}
void SingleInstance::SetStudentsInfo(const student& stu)
{
students.emplace_back(stu);
}
给Lastdll写文件,lastdll用到了topdll中的单例
ExportClass.h
#pragma once
#include <vector>
#include <string>
using namespace std;
#ifdef LASTDLL
#define LASTDLL_API _declspec(dllexport)
#else
#define LASTDLL_API _declspec(dllimport)
#endif
class LASTDLL_API ExportClass
{
public:
ExportClass();
~ExportClass();
int GetPeopleNumber();
};
ExportClass.cpp
#include "pch.h"
#include "ExportClass.h"
#include "../TopDll/SingleInstance.h"
ExportClass::ExportClass()
{
}
ExportClass::~ExportClass()
{
}
int ExportClass::GetPeopleNumber()
{
vector<student> stus;
SingleInstance::GetInstance().GetStudentsInfo(stus);
return stus.size();
}
代码写完了编译一下,编译会出现错误,因为项目没引用静态库,但是会得到topdll和lastdll静态库.lib。
第四步:
配置静态库
要把依赖的库目录和依赖项加到对应的项目链接器中,lastdll要将topdll的静态库库加进去,completeProject要将其他两个库加进去
查找看哪个宏定义是已经对应的位置,其中output对应于debug路径
点击宏可以看到所有编译器已经给出的宏的位置
然后在输入中的附加依赖项中加入对应的lib库,记得分号不要省略(;)
completeProject 需要配置两个lib库
然后在主程序中测试
#include <iostream>
#include "../TopDll/SingleInstance.h"
#include "../HelpDll/ExportClass.h"
int main()
{
vector<student> stus{ {"A",20,true},{"B",15,false },{"C",45,true} };
for (const student& stu : stus)
{
SingleInstance::GetInstance().SetStudentsInfo(stu);
}
ExportClass exportData;
int num = exportData.GetPeopleNumber();
std::cout << num << endl;
}
最终结果
可以将lib库放到专门的文件夹位置,导入库是设置存放的位置。