БГ
Jan. 8, 2019, 3:40 a.m.

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

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

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

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

mydll.h

  1. #ifndef MYDLL_H
  2. #define MYDLL_H
  3.  
  4. #include "mydll_global.h"
  5. #include <QDebug>
  6. #include <QThread>
  7.  
  8. extern "C" {
  9. MYDLLSHARED_EXPORT void startProcess();
  10. MYDLLSHARED_EXPORT void stopProcess();
  11. }
  12. bool stop;
  13. #endif // MYDLL_H

mydll_global.h

  1. #ifndef MYDLL_GLOBAL_H
  2. #define MYDLL_GLOBAL_H
  3.  
  4. #include <QtCore/qglobal.h>
  5.  
  6. #if defined(MYDLL_LIBRARY)
  7. # define MYDLLSHARED_EXPORT Q_DECL_EXPORT
  8. #else
  9. # define MYDLLSHARED_EXPORT Q_DECL_IMPORT
  10. #endif
  11.  
  12. #endif // MYDLL_GLOBAL_H

mydll.cpp

  1. #include "mydll.h"
  2.  
  3. void startProcess()
  4. {
  5. const QThread *curThread = QThread::currentThread();
  6. stop=false;
  7. while(stop==false)
  8. {
  9. curThread->objectName();
  10. curThread->sleep(1);
  11. }
  12. qDebug()<<curThread->objectName();
  13. }
  14.  
  15. void stopProcess()
  16. {
  17. stop=true;
  18. qDebug()<<"process stopped";
  19. }

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

mydll.h

  1. #ifndef MYDLL_H
  2. #define MYDLL_H
  3. #include <QLibrary>
  4. #include <QObject>
  5. #include <QThread>
  6. #include <QDebug>
  7.  
  8. class MyDll : public QObject
  9. {
  10. Q_OBJECT
  11. public:
  12. explicit MyDll(QObject *parent = nullptr);
  13. ~MyDll();
  14. signals:
  15. public slots:
  16. void startDevice();
  17. void stopDevice();
  18. private:
  19. QString lib_name;
  20. QLibrary *lib;
  21. };
  22.  
  23. #endif // MYDLL_H

myprocess.h

  1. #ifndef MYPROCESS_H
  2. #define MYPROCESS_H
  3.  
  4. #include <QObject>
  5. #include <QDebug>
  6. #include <QThread>
  7. #include <QString>
  8. #include "mydll.h"
  9.  
  10. class MyProcess : public QObject
  11. {
  12. Q_OBJECT
  13. public:
  14. explicit MyProcess(QObject *parent = nullptr);
  15.  
  16. signals:
  17.  
  18. public slots:
  19. void startAll();
  20. void startOne(int startDevice);
  21. void stopOne(int stopDevice);
  22. void stopAll();
  23. private:
  24. QList<QThread*> threadsList;
  25. QList<MyDll*> mydllList;
  26. };
  27.  
  28. #endif // MYPROCESS_H

mydll.cpp

  1. #include "mydll.h"
  2.  
  3. MyDll::MyDll(QObject *parent) : QObject(parent)
  4. {
  5.  
  6. }
  7.  
  8. MyDll::~MyDll()
  9. {
  10. delete lib;
  11. }
  12.  
  13. void MyDll::startDevice()
  14. {
  15. static QString suffix = "";
  16. #ifdef QT_DEBUG
  17. suffix = "d";
  18. #endif
  19. QString dll_name="mydll";
  20. lib_name =dll_name + suffix;
  21. lib = new QLibrary;
  22. lib->setFileName(lib_name);
  23. if( !lib->load() ) {
  24. qDebug() << "Loading failed!";
  25. }
  26. typedef void ( *startProcess )();
  27. startProcess input = (startProcess) lib->resolve("startProcess");
  28. if( input ) {
  29. input();
  30. }
  31. }
  32.  
  33. void MyDll::stopDevice()
  34. {
  35. typedef void ( *stopProcess )();
  36. stopProcess input = (stopProcess) lib->resolve("stopProcess");
  37. if( input ) {
  38. input();
  39. }
  40. emit this->thread()->isFinished();
  41. }
  42.  

myprocess.cpp

  1. #include "myprocess.h"
  2.  
  3. MyProcess::MyProcess(QObject *parent) : QObject(parent)
  4. {
  5.  
  6. }
  7.  
  8. void MyProcess::startAll()
  9. {
  10. for(int i=0;i<=5;i++)
  11. {
  12. auto *mydll = new MyDll;
  13. auto *thread = new QThread;
  14. mydll->setObjectName(QString::number(i));
  15. thread->setObjectName(QString::number(i));
  16. mydll->moveToThread(thread);
  17. QObject::connect(thread, SIGNAL(started()),mydll, SLOT(startDevice()));
  18. QObject::connect(thread, SIGNAL(finished()),mydll, SLOT(deleteLater()));
  19. thread->start();
  20. threadsList.append(thread);
  21. mydllList.append(mydll);
  22.  
  23. }
  24. }
  25.  
  26. void MyProcess::startOne(int startDevice)
  27. {
  28. auto *mydll = new MyDll;
  29. auto *thread = new QThread;
  30. mydll->setObjectName(QString::number(startDevice));
  31. thread->setObjectName(QString::number(startDevice));
  32. mydll->moveToThread(thread);
  33. QObject::connect(thread, SIGNAL(started()),mydll, SLOT(startDevice()));
  34. QObject::connect(thread, SIGNAL(finished()),mydll, SLOT(deleteLater()));
  35. thread->start();
  36. threadsList.append(thread);
  37. mydllList.append(mydll);
  38. }
  39.  
  40. void MyProcess::stopOne(int stopDevice)
  41. {
  42. int i=0;
  43. for(auto m:mydllList){
  44. if(m->objectName()==QString::number(stopDevice))
  45. {
  46. m->stopDevice();
  47. mydllList.removeAt(i);
  48. break;
  49. }
  50. i++;
  51. }
  52. i=0;
  53. for(auto t:threadsList){
  54. if(t->objectName()==QString::number(stopDevice))
  55. {
  56. threadsList.removeAt(i);
  57. break;
  58. }
  59. i++;
  60. }
  61. }
  62.  
  63. void MyProcess::stopAll()
  64. {
  65.  
  66. }

main.cpp

  1. #include <QCoreApplication>
  2. #include <QThread>
  3. #include <QDebug>
  4. #include "myprocess.h"
  5. #include <iostream>
  6. using namespace std;
  7.  
  8. int main(int argc, char *argv[])
  9. {
  10. QCoreApplication a(argc, argv);
  11. QThread *thread = new QThread;
  12. MyProcess *process = new MyProcess;
  13. process->moveToThread(thread);
  14. QObject::connect(thread, &QThread::started, process, &MyProcess::startAll);
  15. QObject::connect(thread, &QThread::finished, process, &MyProcess::deleteLater);
  16. thread->start();
  17. qDebug()<<"Thread started";
  18. int i;
  19. cin>>i;
  20. process->stopOne(i);
  21. cin>>i;
  22. return 0;
  23. return a.exec();
  24. }
  25.  

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

Do you like it? Share on social networks!

3
Evgenii Legotckoi
  • Jan. 8, 2019, 2:25 p.m.
  • The answer was marked as a solution.

Добрый день.

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

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

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

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

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

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

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

      Evgenii Legotckoi
      • Jan. 8, 2019, 5:03 p.m.
      • (edited)

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

        Comments

        Only authorized users can post comments.
        Please, Log in or Sign up
        • Last comments
        • IscanderChe
          April 12, 2025, 5:12 p.m.
          Добрый день. Спасибо Вам за этот проект и отдельно за ответы на форуме, которые мне очень помогли в некоммерческих пет-проектах. Профессиональным программистом я так и не стал, но узнал мно…
        • AK
          April 1, 2025, 11:41 a.m.
          Добрый день. В данный момент работаю над проектом, где необходимо выводить звук из программы в определенное аудиоустройство (колонки, наушники, виртуальный кабель и т.д). Пишу на Qt5.12.12 поско…
        • Evgenii Legotckoi
          March 9, 2025, 9:02 p.m.
          К сожалению, я этого подсказать не могу, поскольку у меня нет необходимости в обходе блокировок и т.д. Поэтому я и не задавался решением этой проблемы. Ну выглядит так, что вам действитель…
        • VP
          March 9, 2025, 4:14 p.m.
          Здравствуйте! Я устанавливал Qt6 из исходников а также Qt Creator по отдельности. Все компоненты, связанные с разработкой для Android, установлены. Кроме одного... Когда пытаюсь скомпилиров…
        • ИМ
          Nov. 22, 2024, 9:51 p.m.
          Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…