Solved Sharing singletons between the main application and loaded plugins
-
I have my main application and a shared library/plugin that is loaded at runtime using QPluginLoader.
Both use a singleton logger for logging events.
The main application initializes the logger. The logger is implemented as a static member variable of the logger class.
However, when loading my plugin at runtime, it appears that the plugin references a different instance of the global logger.
Is there a way to make it so that the plugin references the global logger that was initialized by the main application? I've tried using the different QPluginLoader hints, but none of them achieved my desired result.
-
Hi,
Where do you implement that Singleton ?
A static variable in some file doesn't make a singleton. Did you follow the pattern properly when implementing it ? -
@sgaist The singleton is a static member variable of the logger class. The logger class has a static function
initialize(some_args)
.In the app's
main()
, I initialize that instance withlogger::intialize(some_args)
. Then all access to the logger is done throughlogger::instance()
. Both the app and the plugin uselogger::instance()
to access the singleton to log events.Note:
- It works as expected when I compile in debug mode, but doesn't work when compiled in release mode.
- The logger is implemented in a static lib that is linked to by both the main app and the plugin
Minimal example:
logger.hpp
class Logger : public QObject { Q_OBJECT Q_DISABLE_COPY(Logger) public: static void initialize(QCoreApplication *parent); static Logger *instance() { return global; } void logEvent(const QString & msg); ~Logger() override; protected: explicit Logger(QCoreApplication *app); private: static Logger *global; };
logger.cpp
Logger *Logger::global = nullptr; void Logger::initialize(QCoreApplication *parent) { if (global == nullptr) { global = new Logger(parent); } }
main.cpp
int main() { QApplication app; Logger::initialize(&app); }
In the app if I do:
qDebug() << Logger::instance()
It outputs the address of the Logger instance
In the plugin if I do:
qDebug() << Logger::instance()
It outputs 0
When compiled in debug mode, both output the address to the same instance.
-
@btse said in Sharing singletons between the main application and loaded plugins:
The logger is implemented in a static lib that is linked to by both the main app and the plugin
And here is your problem: make it a shared library.
The plugin and main application have their own copy of the library and thus its symbols. -
@sgaist Got it, thanks!
I think I'll try to move away from the singleton pattern first and get it working that way.