Политика конфиденциальностиКонтактыО сайтеОтзывыGitHubDonate
© EVILEG 2015-2018
Рекомендует хостинг
TIMEWEB
БГ
7 января 2019 г. 21:40

Динамическая библиотека

динамическая библиот

Доброго времени суток всем!

Есть динамическая библиотека:

mydll.h

#ifndef MYDLL_H
#define MYDLL_H

#include "mydll_global.h"
#include <QDebug>
#include <QThread>

extern "C" {
MYDLLSHARED_EXPORT void startProcess();
MYDLLSHARED_EXPORT void stopProcess();
}
bool stop;
#endif // MYDLL_H

mydll_global.h

#ifndef MYDLL_GLOBAL_H
#define MYDLL_GLOBAL_H

#include <QtCore/qglobal.h>

#if defined(MYDLL_LIBRARY)
#  define MYDLLSHARED_EXPORT Q_DECL_EXPORT
#else
#  define MYDLLSHARED_EXPORT Q_DECL_IMPORT
#endif

#endif // MYDLL_GLOBAL_H

mydll.cpp

#include "mydll.h"

void startProcess()
{
    const QThread *curThread = QThread::currentThread();
    stop=false;
    while(stop==false)
    {                
        curThread->objectName();
        curThread->sleep(1);
    }
    qDebug()<<curThread->objectName();
}

void stopProcess()
{
    stop=true;
    qDebug()<<"process stopped";
}

Есть также проект:

mydll.h

#ifndef MYDLL_H
#define MYDLL_H
#include <QLibrary>
#include <QObject>
#include <QThread>
#include <QDebug>

class MyDll : public QObject
{
    Q_OBJECT
public:
    explicit MyDll(QObject *parent = nullptr);
    ~MyDll();
signals:
public slots:
    void startDevice();
    void stopDevice();
private:
    QString lib_name;
    QLibrary *lib;
};

#endif // MYDLL_H

myprocess.h

#ifndef MYPROCESS_H
#define MYPROCESS_H

#include <QObject>
#include <QDebug>
#include <QThread>
#include <QString>
#include "mydll.h"

class MyProcess : public QObject
{
    Q_OBJECT
public:
    explicit MyProcess(QObject *parent = nullptr);

signals:

public slots:
    void startAll();
    void startOne(int startDevice);
    void stopOne(int stopDevice);
    void stopAll();
private:
    QList<QThread*> threadsList;
    QList<MyDll*> mydllList;
};

#endif // MYPROCESS_H

mydll.cpp

#include "mydll.h"

MyDll::MyDll(QObject *parent) : QObject(parent)
{

}

MyDll::~MyDll()
{
    delete lib;
}

void MyDll::startDevice()
{
    static QString suffix = "";
#ifdef QT_DEBUG
    suffix = "d";
#endif
    QString dll_name="mydll";
    lib_name =dll_name + suffix;
    lib = new QLibrary;
    lib->setFileName(lib_name);
    if( !lib->load() ) {
        qDebug() << "Loading failed!";
    }
    typedef void ( *startProcess )();
    startProcess input = (startProcess) lib->resolve("startProcess");
    if( input ) {
        input();
    }
}

void MyDll::stopDevice()
{
    typedef void ( *stopProcess )();
    stopProcess input = (stopProcess) lib->resolve("stopProcess");
    if( input ) {
        input();
    }
    emit this->thread()->isFinished();
}

myprocess.cpp

#include "myprocess.h"

MyProcess::MyProcess(QObject *parent) : QObject(parent)
{

}

void MyProcess::startAll()
{
    for(int i=0;i<=5;i++)
    {
        auto *mydll = new MyDll;
        auto *thread = new QThread;
        mydll->setObjectName(QString::number(i));
        thread->setObjectName(QString::number(i));
        mydll->moveToThread(thread);
        QObject::connect(thread, SIGNAL(started()),mydll, SLOT(startDevice()));
        QObject::connect(thread, SIGNAL(finished()),mydll, SLOT(deleteLater()));
        thread->start();
        threadsList.append(thread);
        mydllList.append(mydll);

    }
}

void MyProcess::startOne(int startDevice)
{
    auto *mydll = new MyDll;
    auto *thread = new QThread;
    mydll->setObjectName(QString::number(startDevice));
    thread->setObjectName(QString::number(startDevice));
    mydll->moveToThread(thread);
    QObject::connect(thread, SIGNAL(started()),mydll, SLOT(startDevice()));
    QObject::connect(thread, SIGNAL(finished()),mydll, SLOT(deleteLater()));
    thread->start();
    threadsList.append(thread);
    mydllList.append(mydll);
}

void MyProcess::stopOne(int stopDevice)
{
    int i=0;
    for(auto m:mydllList){
        if(m->objectName()==QString::number(stopDevice))
        {
            m->stopDevice();
            mydllList.removeAt(i);
            break;
        }
        i++;
    }
    i=0;
    for(auto t:threadsList){
        if(t->objectName()==QString::number(stopDevice))
        {
            threadsList.removeAt(i);
            break;
        }
        i++;
    }
}

void MyProcess::stopAll()
{

}

main.cpp

#include <QCoreApplication>
#include <QThread>
#include <QDebug>
#include "myprocess.h"
#include <iostream>
using namespace std;

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QThread *thread = new QThread;
    MyProcess *process = new MyProcess;
    process->moveToThread(thread);
    QObject::connect(thread, &QThread::started, process, &MyProcess::startAll);
    QObject::connect(thread, &QThread::finished, process, &MyProcess::deleteLater);
    thread->start();
    qDebug()<<"Thread started";
    int i;
    cin>>i;
    process->stopOne(i);
    cin>>i;
    return 0;
    return a.exec();
}

Проблема заключается в следующем: при попытке остановить определенный процесс, все остальные тоже завершаются. В динамической библиотеке переменная stop для всех принимает значение true. Как такое возможно и можно ли этого избежать? Вроде у каждого потока свой экземпляр lib. Или я ошибаюсь?

3

Добрый день.

Не понятно, зачем вы вообще используете QLibrary. Создали бы класс с теми методами, а потом создавали бы объект того класса в своём приложении.

Здесь же вы подгружаете через QLibrary многократно одно и ту же библиотеку, хотя как правило это делают один раз. Возможно, что там указатель идёт на одно и тоже, поэтому и потоки сразу все схлопываются.

Сделайте с классом и без QLibrary, как показано было в статье, по которой вы вопрос задали.

Вроде у каждого потока свой экземпляр lib. Или я ошибаюсь?

Как я понимаю, экземляр QLibrary там разный, а вот содержит этот экземпляр всегда одну и ту же библиотеку. Не сталкивался с такой ситуацией, но по мне это не совсем корректный подход сам по себе. Лучше сделать класс, с нужным вам методами и создавать его экземпляр, как было показано в статье.

0
БГ

Весь смысл в том, что у меня будут несколько библиотек, каждый из которых мог бы подгружаться неограниченное количество раз. В каждом из них будут методы с одними и теми же названиями, но с разным функционалом.

Например: программа запущена и есть необходимость дополнить функционал одной из библиотек. Я завершаю только те потоки, которые используют эту библиотеку, остальные потоки, которые используют другие библиотеки остаются работать. После замены библиотеки я вновь запускаю остановленные потоки и они уже работают с дополненным функционалом.

0

Извините, но идея бредовая. Вы превратили библиотеки в классы по сути. И вместо того, чтобы написать одну нормальную библиотеку с некоторыми классами, которые будут иметь возможность переопределения методов и имплементации для конкретных реализаций, Вы пытаетсь подгружать библиотеки как инстансы классов. Для переопределения методов и т.д. есть полиморфизм и объектное программирование. А то что вы делаете... это какая-то ерунда.

0

Комментарии

Только авторизованные пользователи могут публиковать комментарии.
Пожалуйста, авторизуйтесь или зарегистрируйтесь
A
22 января 2019 г. 21:22
Allyonz

C++ - Тест 001. Первая программа и типы данных

  • Результат:40баллов,
  • Очки рейтинга-8
A
22 января 2019 г. 14:15
Alex

Qt - Тест 001. Сигналы и слоты

  • Результат:89баллов,
  • Очки рейтинга6
IO
20 января 2019 г. 18:39
Ivan Otreshko

C++ - Тест 003. Условия и циклы

  • Результат:0баллов,
  • Очки рейтинга-10
Последние комментарии
22 января 2019 г. 13:17
Евгений Легоцкой

Создайте тогда тему здесь на форуме в разделе Qt с выкладками кода и вашими попытками внедрения делегата, позже гляну или может кто-то ещё глянет из опытных пользователей.
I
22 января 2019 г. 13:13
IscanderChe

Не проще тогда использовать сразу кастомный делегат с чекбоксом? Я попробовал, но там засада в том, что чекбокс показывается только при щелчке на ячейку, а дефолтно показывается значение. Как ...
22 января 2019 г. 12:15
Евгений Легоцкой

Если будет не приемлемо потом, то тогда через кастомный Item Delegate нужно будет перерисовать ячейки в той колонке.
I
22 января 2019 г. 12:09
IscanderChe

Получилось приемлемо. Спасибо!Нюанс только в том, что поле рядом с чекбоксом не пропадает, оно просто пустое, что видно при выделении ячейки. Но этого достаточно.
22 января 2019 г. 11:50
Евгений Легоцкой

Переопределить метод data для той колонки и роли Qt::DisplayRole, чтобы в том случае возвращался QVariant() я так думаю... Но возможно, что у вас там будут нюансы, если вы туда чекбокс за...
Сейчас обсуждают на форуме
23 января 2019 г. 7:54
Михаиллл

Зарание спасибо.А еще на эту тему можно будет сделать статью. Это контент будет уникальным.
23 января 2019 г. 7:37
Евгений Легоцкой

Hello. Maybe the English will be better for you? I think russian is not native language for you, or did I mistake? Did I undesrtood rightly, that you mean this documentation ( ...
I
22 января 2019 г. 13:45
IscanderChe

Всем добрый день. Суть задачи: надо, чтобы в одной из колонок QTableView вместо хранимого в QSqlTableModel значения выводился чекбокс и при смене состояния чекбокса значения в базе тоже ...
M
22 января 2019 г. 13:15
Max-P85

Евгений, огромное спасибо, все работает!
Присоединяйтесь к нам в социальных сетях

Для зарегистрированных пользователей на сайте присутствует минимальное количество рекламы