БГ
Булат Гиниятов07 січня 2019 р. 16: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. Или я ошибаюсь?

Рекомендуємо хостинг TIMEWEB
Рекомендуємо хостинг TIMEWEB
Стабільний хостинг, на якому розміщується соціальна мережа EVILEG. Для проектів на Django радимо VDS хостинг.

Вам це подобається? Поділіться в соціальних мережах!

3
Evgenii Legotckoi
  • 08 січня 2019 р. 03:25
  • Відповідь була позначена як рішення.

Добрый день.

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

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

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

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

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

    БГ
    • 08 січня 2019 р. 05:58

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

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

      Evgenii Legotckoi
      • 08 січня 2019 р. 06:03
      • (відредаговано)

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

        Коментарі

        Only authorized users can post comments.
        Please, Log in or Sign up
        AD

        C++ - Тест 004. Указатели, Массивы и Циклы

        • Результат:50бали,
        • Рейтинг балів-4
        m
        • molni99
        • 26 жовтня 2024 р. 11:37

        C++ - Тест 004. Указатели, Массивы и Циклы

        • Результат:80бали,
        • Рейтинг балів4
        m
        • molni99
        • 26 жовтня 2024 р. 11:29

        C++ - Тест 004. Указатели, Массивы и Циклы

        • Результат:20бали,
        • Рейтинг балів-10
        Останні коментарі
        ИМ
        Игорь Максимов22 листопада 2024 р. 22:51
        Django - Підручник 017. Налаштуйте сторінку входу до Django Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
        Evgenii Legotckoi
        Evgenii Legotckoi01 листопада 2024 р. 00:37
        Django - Урок 064. Як написати розширення для Python Markdown Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
        A
        ALO1ZE19 жовтня 2024 р. 18:19
        Читалка файлів fb3 на Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
        ИМ
        Игорь Максимов05 жовтня 2024 р. 17:51
        Django - Урок 064. Як написати розширення для Python Markdown Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
        d
        dblas505 липня 2024 р. 21:02
        QML - Урок 016. База даних SQLite та робота з нею в QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
        Тепер обговоріть на форумі
        Evgenii Legotckoi
        Evgenii Legotckoi25 червня 2024 р. 01:11
        добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
        t
        tonypeachey115 листопада 2024 р. 17:04
        google domain [url=https://google.com/]domain[/url] domain [http://www.example.com link title]
        NSProject
        NSProject04 червня 2022 р. 13:49
        Всё ещё разбираюсь с кешем. В следствии прочтения данной статьи. Я принял для себя решение сделать кеширование свойств менеджера модели LikeDislike. И так как установка evileg_core для меня не была возможна, ибо он писался…
        9
        9Anonim25 жовтня 2024 р. 19:10
        Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…

        Слідкуйте за нами в соціальних мережах