在Qt应用程序及其插件中使用单例类



我试图在我的Qt应用程序中使用Singleton类(它是一个名为'PrisLog'的程序范围调试日志记录器)。该程序也有插件。我想让我的单例类对这些插件可用,但这不起作用。据我所知,试图在插件中使用类会导致创建另一个实例。

-单例类只是一个*.cpp和*.h文件,没有别的了。我已经将我的主应用程序和插件分别链接到这些文件…这是正确的做法吗?

-我在下面附加了我的单例类的代码,尽管我认为我已经正确地创建了这个类。如果我在主应用程序的单独类中使用它,它会像预期的那样工作(一个实例)。

编辑:链接应用程序和插件到同一个静态库(单例类)工作。这是我的qmake。

MySingletonLib.pro

TEMPLATE = lib

CONFIG += staticlib

HEADERS += mysingletonlib.h

SOURCES += mysingletonlib.cpp

并且。Pro(也包括#include mysingletonlib.h在myplugin.h)

INCLUDEPATH += path/to/MySingletonLib

LIBS += -Lpath/to/lmysingletonlib -lMySingletonLib

并且。Pro(也包括#include mysingletonlib.h in myapp.h)

INCLUDEPATH += path/to/MySingletonLib

LIBS += -Lpath/to/lmysingletonlib -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

我认为你应该把这个类带到一个静态链接的,但分开的共享dll/so。

如果你的主机应用程序不使用这个类,链接器就不会把它链接到二进制文件中,你的插件也不能使用它。另外:你的二进制文件没有库类接口

您需要确保只存在一个实例。最安全的是,cpp只在整个exe中编译一次。为了确保其他dll可以调用PrisLog::Instance,这个类/函数(即所有公共方法,如果PrisLog)需要用__declspec(dllexport)声明,即使它位于exe中。dll可以动态地找到对象和方法。

顺便说一句:你为什么不使用Qt的日志记录?

最新更新