this is probably a really basic C++ question but I simply cannot find out a way to properly do this:

I need to create some instances of class "QPluginLoader" within a method of my GUI class and want to store these instances within a QList. The QPluginLoader instances have to be available throughout the whole GUI class. But whenever I try to access a QPluginLoader through my QList the program crashes. I assume that is because once out of the scope where I instantiated the QPluginLoader class, it is destroyed, so it's not available outside of the method where I created the QPluginLoader and stored it into the QList.

But how do I make the instance available in the whole class?

Here is what I tried:

mainwindow.h

class MainWindow : public QMainWindow
{
    Q_OBJECT

public slots:
    void onThreadTerminated();

private:
    bool loadPlugins();
    QList<QPluginLoader*> loaderList;
};

mainwindow.cpp

bool MainWindow::loadPlugins()
{
    QDir pluginsDir(qApp->applicationDirPath());
    pluginsDir.cd("plugins");

    foreach (QString fileName, pluginsDir.entryList(QDir::Files))
    {
        QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName));
        QObject* plugin = pluginLoader.instance();

        if (plugin)
        {
            loaderList.push_back(&pluginLoader);
            pluginCount++;
        }
    }
    return false;
}

last but not least, the slot which crashes my program

// SLOT
void MainWindow::onThreadTerminated()
{
    while (!loaderList.isEmpty()) {
       if(loaderList.takeFirst()->isLoaded()) loaderList.takeFirst()->unload();
    }
    loaderList.clear();
}

2 Answers

0
Gaurav Sehgal On
foreach (QString fileName, pluginsDir.entryList(QDir::Files))
{
    QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName));

pluginLoader will be destroyed at the next } and you keep a reference of this destroyed object in loaderList.

Allocate memory for pluginLoader dynamically using new and keep pointers to QPluginLoader in loaderList

Ofcourse you will have to remember to free the allocated memory for QPluginLoaders

0
Some programmer dude On

The problem is these two lines in the loadPlugins function

QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName));
...
loaderList.push_back(&pluginLoader);

The first define the local object pluginLoader. The second pushes a pointer to that local object into the container.

The problem is that when the loop iterates (or ends), the life-time of pluginLoader ends and it is destructed, the pointer to it becomes invalid.

It seems to me that you should not have a container of plugin loaders, but of the actual plugins themselves.

If you really want the plugin loader in the container, you need to create those dynamically with new, or at least use smart pointers for it. Or, as mentioned in a comment to your question, use a container of QPluginLoader objects.