我有一个包含 3 个项目的应用程序(在 MS Visual Studio 中):
- main(包含
main
函数的那个) - 设备(模拟一些硬件设备)
- config(包含其他两个项目的一些配置)
所以依赖图是:
- main取决于device,这取决于配置
- 主要取决于配置
config项目包含一个 Singleton,其中包含一些配置参数。
我决定把设备项目变成一个 DLL。当我这样做时,似乎我在配置项目中有两个单例实例!我想这是一个经典问题,它可能有一个很好的解决方案。那么我该如何解决这个问题?
我用以下(相对较小的)代码重现了这个问题。当然,就我而言,有大约 30 个项目,而不仅仅是 3 个。我只想制作 1 个 DLL(如果可能的话)。
// config.h
#pragma once
#include <string>
#include <map>
class Config
{
public:
static void Initialize();
static int GetConfig(const std::string& name);
private:
std::map<std::string, int> data;
};
// config.cpp
#include "config.h"
static Config g_instance;
void Config::Initialize()
{
g_instance.data["one"] = 1;
g_instance.data["two"] = 2;
}
int Config::GetConfig(const std::string& name)
{
return g_instance.data[name];
}
// device.h
#pragma once
#ifdef _DLL
#define dll_cruft __declspec( dllexport )
#else
#define dll_cruft __declspec( dllimport )
#endif
class dll_cruft Device
{
public:
void Work();
};
// device.cpp
#include "device.h"
#include <iostream>
#include "config.h"
void Device::Work()
{
std::cout << "Device is working: two = " << Config::GetConfig("two") << '\n';
}
// main.cpp
#include <iostream>
#include "config.h"
#include "device.h"
int main()
{
std::cout << "Before initialization in application: one = " << Config::GetConfig("one") << '\n';
Config::Initialize();
std::cout << "After initialization in application: one = " << Config::GetConfig("one") << '\n';
Device().Work();
std::cout << "After working in application: two = " << Config::GetConfig("two") << '\n';
}
输出:
在应用程序初始化之前:一 = 0
在应用程序中初始化后:一 = 1
设备正在工作:两个 = 0
在应用程序中工作后:2 = 2
关于代码的作用和原因的一些解释:
- 主应用程序启动
- 第一次打印只是为了表明单例尚未初始化
- 主应用程序初始化单例
- 第一个打印显示初始化工作
- 主应用程序启动“硬件设备”
- 在 DLL 内部,未初始化单例!我希望它输出
two = 2
- 最后打印显示单例仍在主应用程序中初始化