Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

plugin cache problem



  • Hi!

    I am developing an application that gets some data from a network device. The data is logged, averaged and shown.
    I don't want to kill the application when I change something at showing the data.
    Therefore I put the things to show in a plugin which then shows the data in a widget.
    After a few days of running I want to be able to change something in the plugin, that shows the data, and reload the plugin.

    The application works just fine, but I have one problem:
    The reloaded plugin remains the same. After changing the plugin source and the files, there is always the old plugin reloaded, which isn't existing anymore on the disk.
    Only after restarting the whole application, the new version of the plugin is loaded.
    I found out, that I have to change the filename of the plugin to have it working.
    So for example, initially i load "plugin1.so". If i want to reload it, i have to call it "plugin2.so". Then the newer version is loaded.

    After digging around I found a little bit about "Plugin Cache", but nothing that helps me. Nowhere is mentioned how to clear that cache.

    So basically everything is working. I can load and reload the plugin, but I don't want to have to change the filename, that the new version of the plugin is loaded instead of the old one.

    I am working on Ubuntu 18.04.05 with Qt 5.11.1 and Qt 5.12.10. (5.12.10 is the latest offline installer version currently).

    Here is my code which is loading and reloading the plugin:

    void energymanager_class::load_plugin(plugin_struct *plugin, QString filename, QWidget *widget) {
        if(plugin->loaded == true) {
            return;
        }
    
        plugin->filename = filename;
        plugin->loader = new QPluginLoader();
        plugin->loader->setFileName(plugin->filename);
        plugin->instance = plugin->loader->instance();
        if(plugin->instance) {
            plugin->loaded = 1;
            plugin->error = 0;
            plugin->interface = qobject_cast<plugin_interface_class*>(plugin->instance);
            plugin->widget = new QWidget();
            plugin->widget->setParent(widget);
            plugin->widget->show();
            plugin->interface->set_gen24data_pointer(gen24_data);
            connect(plugin->interface->get_object(), SIGNAL(newdataavailable_signal()), this, SLOT(newdataavailable_slot()), Qt::DirectConnection);
            connect(this, SIGNAL(newdataavailable_signal()), plugin->interface->get_object(), SLOT(newdataavailable_slot()), Qt::DirectConnection);
            plugin->interface->load_ui(plugin->widget);
            plugin->interface->init();
        } else {
            plugin->loaded = 0;
            plugin->error = 1;
            plugin->errorstring = QString("Plugin konnte nicht geladen werden. loader errorString: %1").arg(plugin->loader->errorString());
            qDebug() << plugin->errorstring;
        }
    }
    
    void energymanager_class::unload_plugin(plugin_struct *plugin) {
        plugin->interface->deinit();
        plugin->interface->unload_ui();
        plugin->loader->unload();
    
        QPluginLoader* loader = plugin->loader;
        delete loader;
    
        QWidget* pluginwidget = plugin->widget;
        delete pluginwidget;
    
        zero.zero_plugin(plugin);
    }
    
    void energymanager_class::on_reload_energyflow_triggered() {
        unload_plugin(&plugin_energyflow);
        load_plugin(&plugin_energyflow, "plugins/plugin_energyflow.so", ui->widget_energyflow);
        formsizechanged();
    }
    

    First load_plugin() is called and the plugin is shown.
    After a few days I change the plugin source, recompile it and call on_reload_energyflow_triggered().
    The plugin is reloaded (correctly it seems), but with the old version instead of the new version. The old version isn't existing anymore on the disk.

    How to reload to the new version and flush the plugin cache?


  • Lifetime Qt Champion

    @churchi said in plugin cache problem:

    The old version isn't existing anymore on the disk.

    For sure it is somewhere. Start with env variable QT_DEBUG_PLUGINS and see from where it is loaded.



  • Thanks for the hint, but its taking the correct files.

    My current solution for the problem is renaming the plugin before loading, and renaming it back after loading.
    This is really a verry shitty solution. But its working?

    void energymanager_class::on_reload_energyflow_triggered() {
        QString filename = plugin_energyflow_filename;
        QString filename_new = filename;
        filename_new.append(QString("%1").arg(QDateTime::currentMSecsSinceEpoch()));
        QFile::rename(filename, filename_new);
        unload_plugin(&plugin_energyflow);
        load_plugin(&plugin_energyflow, filename_new, ui->widget_energyflow);
        QFile::rename(filename_new, filename);
        formsizechanged();
    }
    

    So just renaming the file for short is of course bypassing the cache and makes a workaround. But to be honest - i don't want it like that...


  • Lifetime Qt Champion

    @churchi said in plugin cache problem:

    My current solution for the problem is renaming the plugin before loading, and renaming it back after loading.

    I don't understand what you're trying to tell me.



  • Yeah thats weird...
    It also doesn't make sense for me, but it is working.

    1. I change the source of the plugin
    2. I compile the new version
    3. The old plugin is unloaded (by the main application)
    4. The new plugin file is renamed to anything other than before (by the main application) (to fool the cache)
    5. The new plugin is loaded fine (by the main application)
    6. The new plugin is renamed to the old filename (by the main application)
    7. Everything is fine.

    If I don't do the renaming, the old version of the plugin is loaded again although it has definately been replaced on disk.


Log in to reply