Есть Dll, в которой создается Qthread. В Qthread перемещается некий класс, внутри которого используется QProcess для запуска внешнего консольного приложения 7z (для распаковки архивов). Всё это приводит к Heap corruption.
Если заменить использование внешней программы 7z на QZipReader, например, то всё хорошо.
Собственно вопрос: корректно ли использовать такую связку Dll + QThread + QProcess с точки зрения Qt? Если да, то как правильно это сделать, чтобы застраховать себя от Heap corruption?
P.S. система Windows 7 x64, Qt 5.3.2 (mingw482_32)
P.P.S.
Qt в dll инициализируется так:
//*.h
#pragma once
#include <QThread>
#include <QtCore/QMutex>
#include <QApplication>
#include <memory>
class LibrarySingleton : public QThread
{
Q_OBJECT
public:
static LibrarySingleton* Instance();
void close();
~LibrarySingleton();
protected:
LibrarySingleton();
virtual void run();
private:
std::unique_ptr<QApplication> application;
static std::unique_ptr<LibrarySingleton> instance;
static QMutex lock;
};
//*.cpp
#include "librarysingleton.h"
QMutex LibrarySingleton::lock;
std::unique_ptr<LibrarySingleton> LibrarySingleton::instance;
LibrarySingleton* LibrarySingleton::Instance()
{
if (!instance)
{
lock.lock();
if (!instance)
instance = std::unique_ptr<LibrarySingleton> (new LibrarySingleton);
lock.unlock();
}
return instance.get();
}
LibrarySingleton::LibrarySingleton()
{
if (QCoreApplication::instance() == nullptr) /// !!!
{
int argc = 1;
char arg1[] = "library";
char* argv[1] = {arg1};
application = std::unique_ptr<QApplication>(new QApplication(argc, argv));
}
}
void LibrarySingleton::run()
{
if (application)
application->exec();
}
void LibrarySingleton::close()
{
if (application)
{
application.reset();
quit();
wait();
}
instance.reset();
}
При инициализации моей Dll, я делаю так:
LibrarySingleton::Instance()->start();
QThread создается так:
_workThread.reset(new WorkThread(inputPath,targetPath));
QThread* thread = new QThread;
_workThread->moveToThread(thread);
connect(thread, SIGNAL(started()), _workThread.get(), SLOT(process()));
connect(_workThread.get(), SIGNAL(finished()), thread, SLOT(quit()));
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread->start();
QProcess используется следующим образом:
void WorkThread::process()
{
//.....
QProcess *archiveProcess = new QProcess(this);
archiveProcess->start(utils.at(flagUtil)._pathExe, utils.at(flagUtil)._params);
archiveProcess->waitForFinished();
archiveProcess->close();
delete archiveProcess;
//.....
}