Ich habe ein Programm, das ein Singleton verwendet. Dieses Programm lädt eine gemeinsam genutzte Objektbibliothek zur Laufzeit. Diese Bibliothek verwendet auch dasselbe Singleton. Das Problem ist, dass beim Zugriff auf den Singleton aus der Bibliothek eine neue Instanz des Singleton erstellt wird.Laufzeit dynamische Laden und Singletons
Das Programm mit -rdynamic
verknüpft ist, verwende ich -fPIC
für beide und das Laden geschieht wie folgt aus:
std::shared_ptr<Module> createModuleObject(const std::string& filename)
{
if (!fs::exists(filename))
throw std::runtime_error("Library not found: " + std::string(filename));
struct export_vtable* imports;
void *handle = dlopen(filename.c_str(), RTLD_LAZY | RTLD_GLOBAL);
if (handle) {
imports = static_cast<export_vtable*>(dlsym(handle, "exports"));
if (imports)
return std::shared_ptr<Module>(imports->make());
else
throw std::runtime_error("Error trying to find exported function in library!");
} else
throw std::runtime_error("Error trying to load library: " + std::string(filename));
}
Die Bibliothek eine Klasse wie folgt exportiert:
Module* make_instance()
{
return new HelloWorld();
}
struct export_vtable
{
Module* (*make)(void);
};
struct export_vtable exports = { make_instance };
und diese Klasse nutzt vom Singleton.
Dies ist, wie das Singleton erstellt (Configuration.cpp
):
std::unique_ptr<Configuration> Configuration::instance_(nullptr);
std::once_flag Configuration::onlyOnceFlag_;
Configuration& Configuration::instance()
{
if (instance_ == nullptr)
{
std::cout << "INSTANCE IS NULL, CREATING NEW ONE" << std::endl;
std::call_once(Configuration::onlyOnceFlag_,
[] {
Configuration::instance_.reset(new Configuration());
});
}
return *Configuration::instance_;
}
Sowohl das Programm als auch die Bibliothek Link gegen die Configuration.cpp
. Wenn ich das aus der Bibliothek weglasse, erhalte ich einen undefinierten Symbolfehler, wenn ich versuche, auf den Singleton zuzugreifen.
Wer hat eine Idee, wie man das löst? Vielen Dank!
Das ist einer der Gründe ist, warum Singletons eine schlechte Idee sind. Sie funktionieren nicht wie vorgesehen mit dynamisch verknüpften Bibliotheken. Bleiben Sie auch lieber bei [Scott Meyers Singleton Pattern] (https://stackoverflow.com/questions/1008019/c-singleton-design-pattern). – user0042
Mit Singletons ist nichts verkehrt. Bei dieser speziellen Implementierung gibt es zwei Probleme: 1) Sie haben die Kontrolle über die Singleton-Lebensdauer aufgegeben. Das Erstellen von Singleton beim ersten Aufruf der Instanzmethode ist nie eine gute Idee. 2) Ihre Bibliothek erstellt ihr eigenes Singleton, anstatt Singleton anzufordern, das von der übergeordneten Anwendung erstellt wurde. Um diese 'instance()' Methode zu beheben, sollte aus der Hauptanwendung importiert werden. P.S. Scott Meyers Singleton Pattern sollte Antipattern genannt werden. – VTT
Es sollte möglich sein, dasselbe Singleton in der Bibliothek zu verwenden, oder? Das Problem scheint der Singleton in der Bibliothek zu sein, der den anderen beschattet. Eine 'setConfiguration()' Methode oder etwas in der Bibliothek zu haben ist auch keine Option für mich, da es den Zweck irgendwie vereitelt. ** EDIT: ** was meinst du mit "aus der Hauptanwendung importiert"? – Pfaeff