我正在尝试在我的Qt应用程序中使用Singleton类(它是一个名为'PrisLog'的程序范围的调试记录器)。该程序还有插件。我想让我的单例类可用于这些插件,但这不起作用。据我所知,尝试在插件中使用该类会导致另一个实例被创建。
- 单例类只是一个* .cpp和* .h文件,没有别的。我已将我的主应用程序和插件分别链接到这些文件中...这是正确的方法吗?
- 我已经在下面附加了我的单例类代码,但我认为我已正确创建了该类。如果我在主应用程序的不同类中使用它,它会按预期工作(一个实例)。
编辑:将应用程序和插件链接到同一个静态库(单例类)可以正常工作。这是我的qmake * .pro文件的外观:
MySingletonLib.pro
TEMPLATE = lib
CONFIG + = staticlib
HEADERS + = \ mysingletonlib.h
SOURCES + = \ mysingletonlib.cpp
MyPlugin.pro(也包括myplugin.h中的#include mysingletonlib.h)
INCLUDEPATH + = path / to / MySingletonLib
LIBS + = -Lpath / to / MySingletonLib -lMySingletonLib
MyPlugin.pro(也包括myapp.h中的#include mysingletonlib.h)
INCLUDEPATH + = path / to / MySingletonLib
LIBS + = -Lpath / to / MySingletonLib -lMySingletonLib
原始代码:
#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
答案 0 :(得分:0)
我认为你应该把这个类带到一个静态链接但是separeted共享的dll /。
如果您的主机应用程序不使用此类,则链接器根本不会将其链接到二进制文件,并且您的插件无法使用它。另外:你的二进制文件没有库类接口。
答案 1 :(得分:0)
您需要确保只存在一个实例。最安全的是,cpp在整个exe中只编译一次。 为了确保其他DLL可以调用PrisLog :: Instance,这个类/函数(即所有公共方法,如果PrisLog)需要用__declspec(dllexport)声明,即使它位于exe中。 然后,DLL可以动态地找到对象和方法。
BTW:你为什么不使用Qt的日志记录?