2

SingleApplicationプログラムのインスタンスを 1 つしか実行できないクラスを作成しようとしています。私はこれを使用して実装していますQSharedMemory

値を持つキーを使用しない限り、プログラムは正常に動作します"42"。私がやっていることは何か間違っていますか?これは未定義の動作ですか?

メイン.cpp

int main(int argc, char *argv[])
{

    //QApplication a(argc, argv);
    SingleApplication a(argc, argv, "42"); //Does not work with '42'. Will work for any other value. 



    MainWindow w;
    w.show();


    return a.exec();
}

SingleApplication.h

class SingleApplication : public QApplication
{
    Q_OBJECT

public:
    SingleApplication(int &argc, char *argv[], const QString uniqueKey);

    bool alreadyExists() const{ return bAlreadyExists; }

    bool isMasterApp() const { return !alreadyExists(); }

    bool sendMessage(const QString &message);

public slots:
    //void checkForMessages();

signals:
    //void messageAvailable(const QStringList& messages);

private:
    bool bAlreadyExists;
    QSharedMemory sharedMemory;

};

SingleApplication.cpp

SingleApplication::SingleApplication(int &argc, char *argv[], const QString uniqueKey) : QApplication(argc, argv){

    sharedMemory.setKey(uniqueKey);

    //Create if one does not exist already
    if(sharedMemory.create(5000))
    {
        qDebug() << "Created!";

        bAlreadyExists = false;
    }
    else{
        if(sharedMemory.error() == QSharedMemory::AlreadyExists){
            qWarning() << "Program is already running!";
        }
    }
}
4

2 に答える 2

1

あなたが実装した独自の単一アプリケーションの概念全体を、個人的にゼロから削除します。qt-solutions リポジトリには、QtSingleApplicationQt 5 に移植されたクラスも含まれています。あなたはそれを使うことができるはずです。私の謙虚な意見では、車輪の再発明にはほとんど意味がありません。

それでも自分でそれを行うことを主張する場合、キーをコンストラクターに渡し、クラス内でそれを透過的に管理しないという考えは最初は少し奇妙に思えますが、これはケースを作成するための回避策になる可能性がありますより堅牢なソリューション:

SingleApplication::SingleApplication(int &argc, char *argv[], const QString uniqueKey) : QApplication(argc, argv)
{
    sharedMemory.setKey(uniqueKey);
    if (!sharedMemory.create(5000)) {
        while (sharedMemory.error() == QSharedMemory::AlreadyExists) {
            // Set a new key after some string manipulation
            // This just a silly example to have a placeholder here
            // Best would be to increment probably, and you could still use
            // a maximum number of iteration just in case.
            sharedMemory.setKey(sharedMemory.key() + QLatin1String("0"));
            // Try to create it again with the new key
            sharedMemory.create(5000);
        }
        if (sharedMemory.error() != QSharedMemory::NoError)
            qDebug() << "Could not create the shared memory:" << sharedMemory.errorString();
        else
        {
            qDebug() << "Created!";
            bAlreadyExists = false;
        }
    }

}

免責事項: これは単なる疑似コードであり、実際にテストしたことはなく、自分でコンパイルしようとさえしませんでした!

于 2014-11-03T04:36:22.193 に答える