[SOLVED] Simple plugin fails to load



  • Hello,

    I tried to make a simple program with plugins, similar to the "Echo Plugin Example":http://qt-project.org/doc/qt-5/qtwidgets-tools-echoplugin-example.html . However, my program gives the following error:

    "Cannot load library /home/alain/qt/plugins/libtest_plugin.so: (/home/alain/qt/plugins/libtest_plugin.so: undefined symbol: _ZN11Test_plugin4echoEv)"
    Segmentation fault

    Why doesn't it find that function? Did I forget something? These are my files:

    @+qt/
    - test_app/
    main.cpp
    mainwindow.cpp
    mainwindow.h
    test_interface.h
    test_app.pro
    - test_plugin/
    test_plugin.cpp
    test_plugin.h
    test_plugin.pro
    - plugins/
    libtest_plugin.so
    @

    main.cpp:
    @#include "mainwindow.h"
    #include <QApplication>

    int main(int argc, char *argv[])
    {
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec&#40;&#41;;
    

    }
    @

    mainwindow.h:
    @#ifndef MAINWINDOW_H
    #define MAINWINDOW_H

    #include <QMainWindow>
    #include <QDebug>
    #include <QPluginLoader>
    #include "test_interface.h"

    namespace Ui {
    class MainWindow;
    }

    class MainWindow : public QMainWindow
    {
    Q_OBJECT

    public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

    private:
    Ui::MainWindow *ui;
    };

    #endif // MAINWINDOW_H
    @

    mainwindow.cpp:
    @#include "mainwindow.h"
    #include "ui_mainwindow.h"

    MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    ui->setupUi(this);

    QPluginLoader pluginLoader("/home/alain/qt/plugins/libtest_plugin.so");
    QObject *plugin = pluginLoader.instance();
    qDebug() << pluginLoader.errorString();
    qDebug() << qobject_cast<test_interface*>(plugin)->echo();
    

    }

    MainWindow::~MainWindow()
    {
    delete ui;
    }
    @

    test_interface.h:
    @#ifndef TEST_INTERFACE_H
    #define TEST_INTERFACE_H

    #include <QString>
    #include <QObject>
    #include <QtPlugin>

    class test_interface : public QObject
    {
    Q_OBJECT

    public:
    test_interface();
    virtual QString echo(void) = 0;
    };

    Q_DECLARE_INTERFACE(test_interface, "something.unique")

    #endif // TEST_INTERFACE_H
    @

    test_plugin.h:
    @#ifndef TEST_PLUGIN_H
    #define TEST_PLUGIN_H

    #include "test_interface.h"

    class Test_plugin : public test_interface
    {
    Q_OBJECT
    Q_PLUGIN_METADATA(IID "something.unique")
    Q_INTERFACES(test_interface)

    public:
    Test_plugin();
    QString echo(void);
    };

    #endif // TEST_PLUGIN_H
    @

    test_plugin.cpp:
    @#include "test_plugin.h"

    Test_plugin::Test_plugin()
    {
    }

    QString echo(void)
    {
    return QString("Hallo");
    }
    @

    test_app.pro:
    @QT += core gui

    greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

    TARGET = test_app
    TEMPLATE = app

    SOURCES += main.cpp
    mainwindow.cpp

    HEADERS += mainwindow.h
    test_interface.h

    FORMS += mainwindow.ui
    @

    test_plugin.pro:
    @CONFIG += plugin
    TARGET = $$qtLibraryTarget(test_plugin)
    TEMPLATE = lib
    INCLUDEPATH += ../test_app
    DESTDIR = ../plugins
    SOURCES += test_plugin.cpp
    HEADERS += test_plugin.h ../test_app/test_interface.h
    @

    I am using Qt 5.3.1 and Qt Creator 3.2.0 on Arch Linux 64bit.

    Thanks



  • You did not properly implement your Test_plugin::echo() function. You forgot to add Test_plugin:: in front of the implementation in the cpp file.



  • Basic requirement. Interface should not inherit from QObject. Remove QObject inheritance from Interface. Also try to put destructor.

    class test_interface : public QObject

    Also as "t3685" identified, it is issue with implementation as well.



  • Thanks, I overlooked that. I also added a destructor to test_interface and Test_plugin, removed the QObject from the test_interface and let Test_plugin inherit from QObject instead. Unfortunately, it still doesn't work. Now I get that:

    ./test_app: symbol lookup error: home/alain/qt/plugins/libtest_plugin.so: undefined symbol: _ZN14test_interfaceC2Ev

    I ran qmake and rebuilt everything, but it still can't find it.

    And why shouldn't the Interface inherit from QObject? If I, for example, would want to make an interface for a widget, shouldn't the interface inherit from QWidget and through that from QObject? What would be the alternative?

    Thanks


  • Lifetime Qt Champion

    Hi,

    It should not, take this case: you create two interfaces each one deriving from QObject. Now you want to implement these two interfaces in only one class -> you can't because you are trying to derive multiple times from QObject and it's not possible. Same problem if you try to implement one of these .interface on a QWidget

    Take a look at the Plug and Paint and it's friends examples, they provide also a good starting point.



  • Thanks, I see now that the interface doesn't have to inherit from QWidget to provide it's functions. However, I still can't see why my program fails.



  • I found the problem. I didn't implement the constructor in the interface. Changing this:

    @public:
    test_interface();@

    to this

    @public:
    test_interface(){}@

    or removing the constructor completely solved my problem.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.