Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Unload Plugin in Qt 4.8
Forum Updated to NodeBB v4.3 + New Features

Unload Plugin in Qt 4.8

Scheduled Pinned Locked Moved Unsolved General and Desktop
10 Posts 4 Posters 639 Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    D Offline
    DmitryTS
    wrote on last edited by
    #1

    Hello everyone,
    I'm trying to implement a plugin application that is launched from my main application by clicking on a simple button, I can't implement unloading the plugin by clicking on the close button (already in the plugin itself)
    Is this possible in principle? I load the plugin using QPluginLoader and via the interface.

    Pl45m4P 1 Reply Last reply
    0
    • D DmitryTS

      Hello everyone,
      I'm trying to implement a plugin application that is launched from my main application by clicking on a simple button, I can't implement unloading the plugin by clicking on the close button (already in the plugin itself)
      Is this possible in principle? I load the plugin using QPluginLoader and via the interface.

      Pl45m4P Offline
      Pl45m4P Offline
      Pl45m4
      wrote on last edited by Pl45m4
      #2

      @DmitryTS

      The documentation says:

      Once loaded, plugins remain in memory until all instances of QPluginLoader has been unloaded, or until the application terminates. You can attempt to unload a plugin using unload(), but if other instances of QPluginLoader are using the same library, the call will fail, and unloading will only happen when every instance has called unload(). Right before the unloading happens, the root component will also be deleted.

      (https://doc.qt.io/qt-6/qpluginloader.html#details)

      And why do you use such ancient version of Qt?


      If debugging is the process of removing software bugs, then programming must be the process of putting them in.

      ~E. W. Dijkstra

      D 1 Reply Last reply
      1
      • Pl45m4P Pl45m4

        @DmitryTS

        The documentation says:

        Once loaded, plugins remain in memory until all instances of QPluginLoader has been unloaded, or until the application terminates. You can attempt to unload a plugin using unload(), but if other instances of QPluginLoader are using the same library, the call will fail, and unloading will only happen when every instance has called unload(). Right before the unloading happens, the root component will also be deleted.

        (https://doc.qt.io/qt-6/qpluginloader.html#details)

        And why do you use such ancient version of Qt?

        D Offline
        D Offline
        DmitryTS
        wrote on last edited by
        #3

        @Pl45m4 working on devices that not supported normal versions of qt :(, and I almost memorized the documentation about plugins, but it doesn’t really help, I’m already trying to remake my application so that the plugin sends a signal to the main application, and the main application itself unloaded this plugin, but for some reason a Segmentation fault error appears, although when checking, bool result = loader.unload)), result - true, I tried doing something else - delete loader.instance(), everything works, but if, for example, you open several plugin windows at once, for some reason only the most recently opened ones will close

        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #4

          Hi,

          What do you mean by "plugin application" ?
          Are you extending your application with new widgets or are you starting external applications through your plugin ?

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          D 1 Reply Last reply
          0
          • SGaistS SGaist

            Hi,

            What do you mean by "plugin application" ?
            Are you extending your application with new widgets or are you starting external applications through your plugin ?

            D Offline
            D Offline
            DmitryTS
            wrote on last edited by
            #5

            @SGaist hi, I’m expanding my main application, well, in short: my plugin application is a text editor, I want that in my main application, when I click on a file -> open (my plugin) -> my text editor with this file will load

            1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #6

              Do you have a stack trace of your crash ?

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              D 1 Reply Last reply
              0
              • SGaistS SGaist

                Do you have a stack trace of your crash ?

                D Offline
                D Offline
                DmitryTS
                wrote on last edited by
                #7

                @SGaist I think it will be easier if I provide a piece of code

                I have 2 app: AppPlugin and MainApp
                In these two app there is a class that stores global variables:

                GlobalData.h
                …
                extern MainWindow *mainWindow;
                extern QWidget *wgt;
                extern QGraphicsScene *scene;
                extern QGraphicsView *view;
                extern QDeclarativeEngine *engine;
                …
                <<<<<<<<
                GlobalData.cpp
                …
                MainWindow *mainWindow;
                QWidget *wgt;
                QGraphicsScene *scene;
                QGraphicsView *view;
                QDeclarativeEngine *engine;
                …
                <<<<<<<<

                AppPlugin:

                int main(…)
                {
                QApplication a(argc, argv);
                mainWindow = new MainWindow;
                return a.exec()(
                }
                <<<<

                MainWindow.h
                class MainWindow : public QObject
                {
                MainWindow(QObject * parent = 0);
                ~MainWindow();
                Q_INVOKABLE unloadPlugin();
                signals:
                Void unloadPluginSignal();
                }
                <<<<
                MainWindow.cpp
                MainWindow::MainWindow(QObject *parent) : QObject(parent)
                {
                wgt = new QWidget;
                …
                scene = new QGraphicsScene(…);
                …
                view = new QGraphicsView(…);
                …
                engine = new QDeclarativeEngine;
                //
                add main.qml on scene
                //
                wgt->show();
                }
                MainWindow::~MainWindow()
                {
                qDebug() << “delete mainModel”;
                }

                void MainWindow::unloadPlugin()
                {
                emit unloadPluginSignal();
                }

                <<<<

                PluginInterface.h

                class PluginInterface : public QObject
                {
                Q_OBJECT
                public:
                virtual ~PluginInterface(){}
                virtual void getEngine(QDeclarativeEngine *extEngine) =0;
                Q_SIGNAL void signalFromPlugin();
                };
                Q_DECLARE_INTERFACE(PluginInterface, “MyTestPlugin”)

                <<<<<
                Plugin.h
                class Plugin : public PluginInterface
                {
                Q_OBJECT
                Q_INTERFACES(PluginInterface)
                public:
                ~Plugin();
                void getEngine();
                public slots:
                void unloadPlugin();
                }
                <<<<<

                Plugin.cpp
                Plugin::~Plugin()
                {
                qDebug << “delete plugin”;
                }

                void Plugin::getEngine()
                {
                //
                may get the engine from the main application, but in principle I don’t need it.
                //
                mainWindow = new MainWindow;
                connect(mainWindow, SIGNAL(unloadPluginSignal()), this, SLOT(unloadPlugin()));
                }
                void Plugin::unloadPlugin()
                {
                emit signalFromPlugin();
                }

                Q_EXPORT_PLUGIN2(PluginInterface, Plugin)

                Then from main.qml I call the slot with MainWindow - unloadPlugin

                main.qml
                Rectangel{
                …
                Rectangel{
                …
                MouseArea{
                anchors.fill: parent
                onClocked: mainWindowContext.unloadPlugin()
                }

                }
                }

                ——-/—/————————
                MainApp:

                Int main(…)
                {
                QApplicatino a(argc, argv);
                mainWindow = new MainWindow;
                return a.exec();
                }

                MainWindow.h

                class MainWindow: public QObject
                {
                Q_OBJECT
                public:
                MainModel();

                Q_INVOKABLE bool loadPlugin();

                public slots:
                void unloadPlugin();

                private:
                PluginInterface *plugin;
                QPluginLoader *loader;
                }

                MainWindow.cpp

                MainWindow::MainWindow()
                {
                wgt = new QWidget;
                …
                scene = new QGraphicsScene(…);
                …
                view = new QGraphicsView(…);
                …
                engine = new QDeclarativeEngine;
                //
                add main.qml on scene
                //
                wgt->show();
                }

                bool MainWindow::loadPlugin()
                {
                loader = new QPluginLoader(//src plugin//);
                If(loader->load())
                {
                If( plugin = qobject_cast<PluginInterface*>(loader->instance()))
                {
                plugin->getEngine(engine);
                connect(plugin, SIGNAL(signalFromPlugin()), this, SLOT(unloadPlugin()));
                return true;
                }
                return false
                }
                }

                bool Plugin::unloadPlugin()
                {
                bool result = loader->unload();
                qDebug() << result;
                }

                after clicking on the button in ManApp and calling the loadPlugin method, it is loaded and displayed, but as soon as I click on the close button of this plugin, the unloadPlugin method is called on me and the result variable will return true, after that the application immediately crashes with segmentationFault

                Pl45m4P 1 Reply Last reply
                0
                • D DmitryTS

                  @SGaist I think it will be easier if I provide a piece of code

                  I have 2 app: AppPlugin and MainApp
                  In these two app there is a class that stores global variables:

                  GlobalData.h
                  …
                  extern MainWindow *mainWindow;
                  extern QWidget *wgt;
                  extern QGraphicsScene *scene;
                  extern QGraphicsView *view;
                  extern QDeclarativeEngine *engine;
                  …
                  <<<<<<<<
                  GlobalData.cpp
                  …
                  MainWindow *mainWindow;
                  QWidget *wgt;
                  QGraphicsScene *scene;
                  QGraphicsView *view;
                  QDeclarativeEngine *engine;
                  …
                  <<<<<<<<

                  AppPlugin:

                  int main(…)
                  {
                  QApplication a(argc, argv);
                  mainWindow = new MainWindow;
                  return a.exec()(
                  }
                  <<<<

                  MainWindow.h
                  class MainWindow : public QObject
                  {
                  MainWindow(QObject * parent = 0);
                  ~MainWindow();
                  Q_INVOKABLE unloadPlugin();
                  signals:
                  Void unloadPluginSignal();
                  }
                  <<<<
                  MainWindow.cpp
                  MainWindow::MainWindow(QObject *parent) : QObject(parent)
                  {
                  wgt = new QWidget;
                  …
                  scene = new QGraphicsScene(…);
                  …
                  view = new QGraphicsView(…);
                  …
                  engine = new QDeclarativeEngine;
                  //
                  add main.qml on scene
                  //
                  wgt->show();
                  }
                  MainWindow::~MainWindow()
                  {
                  qDebug() << “delete mainModel”;
                  }

                  void MainWindow::unloadPlugin()
                  {
                  emit unloadPluginSignal();
                  }

                  <<<<

                  PluginInterface.h

                  class PluginInterface : public QObject
                  {
                  Q_OBJECT
                  public:
                  virtual ~PluginInterface(){}
                  virtual void getEngine(QDeclarativeEngine *extEngine) =0;
                  Q_SIGNAL void signalFromPlugin();
                  };
                  Q_DECLARE_INTERFACE(PluginInterface, “MyTestPlugin”)

                  <<<<<
                  Plugin.h
                  class Plugin : public PluginInterface
                  {
                  Q_OBJECT
                  Q_INTERFACES(PluginInterface)
                  public:
                  ~Plugin();
                  void getEngine();
                  public slots:
                  void unloadPlugin();
                  }
                  <<<<<

                  Plugin.cpp
                  Plugin::~Plugin()
                  {
                  qDebug << “delete plugin”;
                  }

                  void Plugin::getEngine()
                  {
                  //
                  may get the engine from the main application, but in principle I don’t need it.
                  //
                  mainWindow = new MainWindow;
                  connect(mainWindow, SIGNAL(unloadPluginSignal()), this, SLOT(unloadPlugin()));
                  }
                  void Plugin::unloadPlugin()
                  {
                  emit signalFromPlugin();
                  }

                  Q_EXPORT_PLUGIN2(PluginInterface, Plugin)

                  Then from main.qml I call the slot with MainWindow - unloadPlugin

                  main.qml
                  Rectangel{
                  …
                  Rectangel{
                  …
                  MouseArea{
                  anchors.fill: parent
                  onClocked: mainWindowContext.unloadPlugin()
                  }

                  }
                  }

                  ——-/—/————————
                  MainApp:

                  Int main(…)
                  {
                  QApplicatino a(argc, argv);
                  mainWindow = new MainWindow;
                  return a.exec();
                  }

                  MainWindow.h

                  class MainWindow: public QObject
                  {
                  Q_OBJECT
                  public:
                  MainModel();

                  Q_INVOKABLE bool loadPlugin();

                  public slots:
                  void unloadPlugin();

                  private:
                  PluginInterface *plugin;
                  QPluginLoader *loader;
                  }

                  MainWindow.cpp

                  MainWindow::MainWindow()
                  {
                  wgt = new QWidget;
                  …
                  scene = new QGraphicsScene(…);
                  …
                  view = new QGraphicsView(…);
                  …
                  engine = new QDeclarativeEngine;
                  //
                  add main.qml on scene
                  //
                  wgt->show();
                  }

                  bool MainWindow::loadPlugin()
                  {
                  loader = new QPluginLoader(//src plugin//);
                  If(loader->load())
                  {
                  If( plugin = qobject_cast<PluginInterface*>(loader->instance()))
                  {
                  plugin->getEngine(engine);
                  connect(plugin, SIGNAL(signalFromPlugin()), this, SLOT(unloadPlugin()));
                  return true;
                  }
                  return false
                  }
                  }

                  bool Plugin::unloadPlugin()
                  {
                  bool result = loader->unload();
                  qDebug() << result;
                  }

                  after clicking on the button in ManApp and calling the loadPlugin method, it is loaded and displayed, but as soon as I click on the close button of this plugin, the unloadPlugin method is called on me and the result variable will return true, after that the application immediately crashes with segmentationFault

                  Pl45m4P Offline
                  Pl45m4P Offline
                  Pl45m4
                  wrote on last edited by
                  #8

                  @DmitryTS said in Unload Plugin in Qt 4.8:

                  it is loaded and displayed, but as soon as I click on the close button of this plugin, the unloadPlugin method is called on me and the result variable will return true, after that the application immediately crashes with segmentationFault

                  I think because you have only one MainWindow pointer for the plugin and the program itself...
                  The "unload" clears the objects in GlobalData and this is where you mainprogram is also stored.

                  Othewise, as usual, debug and see where it crashes (what's the last call which causes the segfault).


                  If debugging is the process of removing software bugs, then programming must be the process of putting them in.

                  ~E. W. Dijkstra

                  D 1 Reply Last reply
                  0
                  • Pl45m4P Pl45m4

                    @DmitryTS said in Unload Plugin in Qt 4.8:

                    it is loaded and displayed, but as soon as I click on the close button of this plugin, the unloadPlugin method is called on me and the result variable will return true, after that the application immediately crashes with segmentationFault

                    I think because you have only one MainWindow pointer for the plugin and the program itself...
                    The "unload" clears the objects in GlobalData and this is where you mainprogram is also stored.

                    Othewise, as usual, debug and see where it crashes (what's the last call which causes the segfault).

                    D Offline
                    D Offline
                    DmitryTS
                    wrote on last edited by
                    #9

                    @Pl45m4 a little bit wrong, I have this file with global variables in two programs so that the plugin has its own independent engine, at first I thought maybe this was a problem due to the same names, I’ve already renamed it - now to GlobalData in MainApp: MainWindow *appWindow

                    After click and call function unloadPlugin:
                    bool Plugin::unloadPlugin()

                    {

                    bool result = loader->unload();
                    
qDebug() << result;
                    
}

                    but it crashes strangely, it outputs from the unloadPlugin method, the result variable is true and immediately segmentationFault, I tried it a little differently:

                    bool Plugin::unloadPlugin()
{
delete plugin;
}
                    and then the program begins to have a completely different behavior, every other time it works as I need, and the frequency is incomprehensible, that is, the plugin can close normally 5 times, but break down on the 6th.

                    I honestly still can’t fully understand, when unloading a plugin, do I need to explicitly free up memory: delete mainWindow? Or will it recursively release itself when the plugin is unloaded?

                    1 Reply Last reply
                    0
                    • jsulmJ Offline
                      jsulmJ Offline
                      jsulm
                      Lifetime Qt Champion
                      wrote on last edited by
                      #10

                      As already mentioned: if your app is crashing run it through debugger to see where exactly it happens and post the stack trace after the crash.

                      https://forum.qt.io/topic/113070/qt-code-of-conduct

                      1 Reply Last reply
                      1

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved