简体   繁体   中英

QPluginLoader instance always returns null

I am in the process of building a Qt application. While I have programmed lots of GUI things before and the framework itself isn't presenting a problem, I have not ever programmed anything (outside of C# .NET applications) that has the capability to load plugins. The project I am trying to build has plugins as an integral part of it and I thought the Qt framework looked nice for this because it was almost universally cross-platform and seems to have a very nice system for plugins.

My problem is this: I can't seem to get the QPluginLoader.instance() method to return anything but a null value .

From my readings, this is because it finds no plugin. I think I am probably forgetting to do something, but I can find very little documentation on actually writing plugins (there are examples, but they aren't incredibly detailed). There are plenty of examples of loading plugins and I think I am doing that right, but I haven't really found an example of actually making a plugin.

This is what I have done:

Using Qt-Creator I have created two projects: A windowed application to pretend that it is my plugin receiving application and a Shared Library project to pretend to be the plugin

In my windowed application I have a header file as follows:

#ifndef PLUGININTERFACE_H
#define PLUGININTERFACE_H

#include <QtPlugin>

class QStringList;

class PluginInterface
{
public:
    virtual ~PluginInterface() {};

    virtual QStringList messages() const = 0;
};

Q_DECLARE_INTERFACE(PluginInterface,
                    "com.kevincuzner.LearningPlugins.PluginInterface/1.0")

#endif // PLUGININTERFACE_H

In my shared library application I created a class called ATestPlugin (and this is also the TARGET value of the project):

#ifndef ATESTPLUGIN_H
#define ATESTPLUGIN_H

#include "ATestPlugin_global.h"
#include "../LearningPlugins/PluginInterface.h"

#include <QStringList>


class ATESTPLUGINSHARED_EXPORT ATestPlugin : public PluginInterface, public QObject
{

    Q_OBJECT
    Q_INTERFACES(PluginInterface)

public:
    ATestPlugin();

    virtual QStringList messages() const
    {
        //this part is actually defined in the .cpp file, but I don't feel like pasting that here
        QStringList ret;
        ret << "foo" << "bar" << "noms" << "Hello";

        return ret;
    }
};

#endif // ATESTPLUGIN_H

At the end of the ATestPlugin.cpp file I have placed Q_EXPORT_PLUGIN2(ATestPlugin, ATestPlugin)

Then in my main.cpp file in the main method I do the following (&w points to the main window):

QString text = QFileDialog::getOpenFileName(&w, "Get a file");
QPluginLoader loader(text);
QObject* plugin = loader.instance();
if (plugin)
{
    QMessageBox msgBox;
    msgBox.setText(text);
    msgBox.exec();
}

When I run the program and select libATestPlugin.so from the build directory of my library project in the file dialog that pops up, I see no message box which means *plugin is null. Previously I had the messagebox always pop up and show the selected file name, so I know that part is working.

Does anyone have any ideas as to what I need to do to make my plugin visible to QPluginLoader?

It didn't work for me. Change of your previous TARGET to $$qtLibraryTarget(...) ensures right extensions during build on different platforms.

I had the same problem with QPluginLoader. In few words how I solved it: I create plugin library, let's say lib1.dll which use some stuff from lib2.dll. In my application I try to load lib1 via QPluginLoader.

QPluginLoader loader( adaptersDir.absoluteFilePath(fileName) );
AdapterInterface* adapterIface = qobject_cast<AdapterInterface*>(loader.instance());

In this case loader.instance() returns 0. Solution was to copy lib2.dll into application folder because an application use it for proper load plugin lib1.

After further experimentation I managed to get the plugin to load. I feel sheepish saying this, but it was a classic case of RTFM.

The echo plugin tutorial (which I hadn't found until after I posted the question) had some modifications that had to be made to the .pro file in the library to make it declare the plugin correctly:

The line TARGET = ATestPlugin had to be changed to TARGET = $$qtLibraryTarget(ATestPlugin) . After making this change, my messagebox in the above program popped up and later when I ran qobject_cast< PluginInterface* >(plugin) and then asked ran PluginInterface->messages() I got the list which was implemented in the separate class.

Also, I did change the inheritance order to put QObject first and since it works that way I will probably keep it so (although, I don't know if it made a difference).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM