问题
I'm trying to use a Singleton Class (its a program-wide debug logger called 'PrisLog') across my Qt Application. The program also has plugins. I want to make my singleton class available to those plugins, but this doesn't work. From what I can tell, trying to use the class in the plugin results in another instance being created.
-The singleton class is just a *.cpp and *.h file, nothing else. I've linked both my main application and the plugin to these files individually... is this the right way to do it?
-I've attached my singleton class's code below, though I think I've created the class correctly. If I use it from within separate classes in my main application, it works as expected (one instance).
EDIT: Linking both the application and plugin to the same static lib (the singleton class) works. Here's how my qmake *.pro files looked:
MySingletonLib.pro
TEMPLATE = lib
CONFIG += staticlib
HEADERS += \ mysingletonlib.h
SOURCES += \ mysingletonlib.cpp
MyPlugin.pro (also incl #include mysingletonlib.h in myplugin.h)
INCLUDEPATH += path/to/MySingletonLib
LIBS += -Lpath/to/MySingletonLib -lMySingletonLib
MyPlugin.pro (also incl #include mysingletonlib.h in myapp.h)
INCLUDEPATH += path/to/MySingletonLib
LIBS += -Lpath/to/MySingletonLib -lMySingletonLib
And the original code:
#ifndef PRISLOG_H
#define PRISLOG_H
#include <QFile>
#include <QDir>
#include <QString>
#include <QMutex>
#include <QDebug>
#include <QMutexLocker>
#include <QTextStream>
#include <QDateTime>
// PrisLog (singleton) class definition
class PrisLog
{
public:
static PrisLog* Instance();
void SetLogsPath(QString);
QString GetLogsPath();
void SetDebugDestination(QString);
void SetElmRxDestination(QString);
void SetElmTxDestination(QString);
void SetDlgDestination(QString);
QTextStream* GetDebugStream();
QTextStream* GetElmRxStream();
QTextStream* GetElmTxStream();
QTextStream* GetDlgStream();
QMutex* GetDebugMutex();
private:
PrisLog(); // private constructor
PrisLog(const PrisLog&); // prevent copy constructor
PrisLog& operator=(const PrisLog&); // prevent assignment
static PrisLog* m_Instance;
static bool m_InitFlag;
QString m_appPath;
QFile m_DebugFile;
QTextStream m_DebugStream;
QMutex m_DebugMutex;
QFile m_ElmRxFile;
QTextStream m_ElmRxStream;
QFile m_ElmTxFile;
QTextStream m_ElmTxStream;
QFile m_DlgFile;
QTextStream m_DlgStream;
};
// thread-UNSAFE writer, but less expensive
// use: single stream <--> single thread!
class PrisLogWriter
{
public:
PrisLogWriter(QTextStream*);
~PrisLogWriter();
QTextStream* m_stream;
};
// thread-UNSAFE writer, but less expensive
// this version does not include any formatting
// use: single stream <--> single thread!
class PrisLogRawWriter
{
public:
PrisLogRawWriter(QTextStream*);
~PrisLogRawWriter();
QTextStream* m_stream;
};
// thread-safe writer
// use: single stream <--> many threads
class PrisLogSafeWriter
{
public:
PrisLogSafeWriter(QTextStream*, QMutex*);
~PrisLogSafeWriter();
QTextStream* m_stream;
private:
QMutex* m_mutex;
};
#define PRISLOGDEBUG (*(PrisLogSafeWriter(PrisLog::Instance()->GetDebugStream(), PrisLog::Instance()->GetDebugMutex()).m_stream))
#define PRISLOGELMRX (*(PrisLogWriter(PrisLog::Instance()->GetElmRxStream()).m_stream))
#define PRISLOGELMTX (*(PrisLogWriter(PrisLog::Instance()->GetElmTxStream()).m_stream))
#define PRISLOGDLG (*(PrisLogRawWriter(PrisLog::Instance()->GetDlgStream()).m_stream))
#endif // PRISLOG_H
回答1:
I think you should take this class to a statically linked, but separeted shared dll/so.
If your host application does not use this class, the linker simply won't link it into the binary and your plugin could not use it. Additionally: your binary has no library class interface.
回答2:
You need to make sure, that only one instance exists. The safest is, that the cpp is compiled only once in the overall exe. To make sure that the other DLLs can call PrisLog::Instance, this class/function (i.e. all public methods if PrisLog) needs to be declared with __declspec(dllexport), even if it is located within the exe. The DLLs can then dynamically find the object and method.
BTW: Why don't you use the logging from Qt?
来源:https://stackoverflow.com/questions/6689370/using-a-singleton-class-across-a-qt-application-and-its-plugins