Cómo implementar un Singleton en una aplicación con DLL

Tengo una aplicación (en MS Visual Studio) que contiene 3 proyectos:

principal (el que contiene elmain función)dispositivo (modela algún dispositivo de hardware)configuración (contiene alguna configuración para los otros dos proyectos)

Así que el gráfico de dependencia es:

principal depende dedispositivo, que depende deconfiguraciónprincipal depende deconfiguración

losconfiguración proyecto contiene un Singleton, que contiene algunos parámetros de configuración.

Decidí convertir eldispositivo proyecto en una DLL. Cuando hice esto, parece que obtuve dos instancias del Singleton en elconfiguración ¡proyecto! Supongo que este es un problema clásico, que podría tener una buena solución. Entonces, ¿cómo puedo solucionar esto?

He reproducido el problema con el siguiente código (relativamente pequeño). Por supuesto, en mi caso hay unos 30 proyectos, no solo 3. Y me gustaría hacer solo 1 DLL (si es posible).

<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>

Salida:

Antes de la inicialización en la aplicación: uno = 0

Después de la inicialización en la aplicación: uno = 1

El dispositivo está funcionando: dos = 0

Después de trabajar en la aplicación: dos = 2

Algunas explicaciones sobre lo que hace el código y por qué:

Se inicia la aplicación principalLa primera impresión es solo para mostrar que el singleton aún no está inicializadoLa aplicación principal inicializa el singleton.La primera impresión muestra que la inicialización funcionó.La aplicación principal inicia el "dispositivo de hardware"Dentro de la DLL, el singleton no se inicializa! Espero que salgatwo = 2La última impresión muestra que el singleton todavía está inicializado en la aplicación principal

Respuestas a la pregunta(3)

Su respuesta a la pregunta