Como implementar um singleton em um aplicativo com DLL

Eu tenho um aplicativo (no MS Visual Studio) que contém 3 projetos:

a Principal (aquele que contém omain função)dispositivo (modela algum dispositivo de hardware)config (contém alguma configuração para outros dois projetos)

Portanto, o gráfico de dependência é:

a Principal depende dedispositivo, que dependeconfiga Principal depende deconfig

oconfig O projeto contém um Singleton, que contém alguns parâmetros de configuração.

Eu decidi virar odispositivo projeto em uma DLL. Quando eu fiz isso, parece que eu tenho duas instâncias do Singleton noconfig projeto! Eu acho que este é um problema clássico, que pode ter uma boa solução. Então, como posso consertar isso?

Eu reproduzi o problema com o seguinte código (relativamente pequeno). Claro, no meu caso existem cerca de 30 projetos, não apenas 3. E eu gostaria de fazer apenas 1 DLL (se possível).

<code>// 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];
}
</code>
<code>// 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';
}
</code>
<code>// 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';
}
</code>

Saída:

Antes da inicialização na aplicação: um = 0

Após a inicialização na aplicação: um = 1

O dispositivo está funcionando: dois = 0

Depois de trabalhar na aplicação: dois = 2

Algumas explicações sobre o que o código faz e por quê:

A aplicação principal começaA primeira impressão é apenas para mostrar que o singleton ainda não foi inicializadoA aplicação principal inicializa o singletonA primeira impressão mostra que a inicialização funcionouA aplicação principal inicia o "dispositivo de hardware"Dentro da DLL, o singleton não é inicializado! Espero que saiatwo = 2A última impressão mostra que o singleton ainda está inicializado no aplicativo principal

questionAnswers(3)

yourAnswerToTheQuestion