БГ
Булат ГиниятовҚаң. 7, 2019, 4: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
  • Қаң. 8, 2019, 3:25 Т.Ж.
  • Жауап шешім ретінде белгіленді.

Добрый день.

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

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

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

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

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

    БГ
    • Қаң. 8, 2019, 5:58 Т.Ж.

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

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

      Evgenii Legotckoi
      • Қаң. 8, 2019, 6:03 Т.Ж.
      • (өңделген)

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

        Пікірлер

        Тек рұқсаты бар пайдаланушылар ғана пікір қалдыра алады.
        Кіріңіз немесе Тіркеліңіз
        OI
        • Ora Iro
        • Жел. 24, 2024, 6:38 Т.Ж.

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

        • Нәтиже:40ұпай,
        • Бағалау ұпайлары-8
        AD

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

        • Нәтиже:50ұпай,
        • Бағалау ұпайлары-4
        m
        • molni99
        • Қаз. 26, 2024, 1:37 Т.Ж.

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

        • Нәтиже:80ұпай,
        • Бағалау ұпайлары4
        Соңғы пікірлер
        ИМ
        Игорь МаксимовҚар. 22, 2024, 11:51 Т.Ж.
        Django - Оқулық 017. Теңшелген Django кіру беті Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
        Evgenii Legotckoi
        Evgenii LegotckoiҚаз. 31, 2024, 2:37 Т.Қ.
        Django - Сабақ 064. Python Markdown кеңейтімін қалай жазуға болады Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
        A
        ALO1ZEҚаз. 19, 2024, 8:19 Т.Ж.
        Qt Creator көмегімен fb3 файл оқу құралы Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
        ИМ
        Игорь МаксимовҚаз. 5, 2024, 7:51 Т.Ж.
        Django - Сабақ 064. Python Markdown кеңейтімін қалай жазуға болады Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
        d
        dblas5Шілде 5, 2024, 11:02 Т.Ж.
        QML - Сабақ 016. SQLite деректер қоры және онымен QML Qt-та жұмыс істеу Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
        Енді форумда талқылаңыз
        n
        nklyҚаң. 3, 2025, 2:52 Т.Ж.
        Нужно запретить перемещение только некоторых итемов, остальные перемещать можно. Вопрос решен. Узнать QModelIndex элемента на который мы перетаскиваем другой элемент, можно с помощью функции indexAt(event->position().toPoint()) представления QTreeViev вызываемой в переопр…
        AW
        Ayden WatkinsҚаң. 2, 2025, 12:09 Т.Ж.
        Why Paying for a Research Paper Can Be a Smart Choice Writing a research paper can be a daunting task, especially when faced with tight deadlines, complex topics, or a lack of resources. For many students, paying for a research paper is a practical…
        p
        pimacontrols85Жел. 31, 2024, 9:39 Т.Ж.
        Finding the Right Rittal Small Enclosure for Your Needs Rittal is a leading manufacturer of enclosures for industrial and IT applications. Their small enclosures offer a compact and reliable solution for a wide range of needs, from housing electronic…
        Donald Randolph
        Donald RandolphЖел. 30, 2024, 2:59 Т.Ж.
        Personal Injury lawyer Santa Monica As an experienced Santa Monica personal injury lawyer, Donald C. Randolph has recovered over $100 Million in verdicts and settlements for our clients. In severe injury cases, this compensation i…
        Nirvana Yoga School
        Nirvana Yoga SchoolЖел. 30, 2024, 5:13 Т.Ж.
        OAuth2.0 через VK, получение email Nirvana Yoga School is one of the most trusted and reputed traditional Rishikesh yoga courses , India certified by Yoga Alliance, USA. We aim to spread traditional yoga teachings so t…

        Бізді әлеуметтік желілерде бақылаңыз