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

Signals Inheritance: undefined symbol



  • I'm developing a C++ shared library (plugin) to my Qt GUI application.

    Both: main app and plugin projects compile without any warnings or errors. All ok!

    My plugin have 2 classes:

    • Plugin_API class (shared library interface)
    • Plugin class

    So Plugin inherits all public and protected methods (signals too, right?) from Plugin_API:

    class Plugin : public Plugin_API
    

    Inside Plugin_API class I have a signal called sendMsg:

    Inside of Plugin_API.h file:

    void sendMsg(const QString source, const MSG_TYPE msgType, const QString msg) const;
    

    When I run my main application, it loads the plugin and connects the signal with a app slot with success! No errors!

    bool conn1 = connect(plugin, &Plugin_API::sendMsg, this, &App::receivedMsg);
    
    if (!conn1) {
        sendErrorMsg(tr("Unable to connect: %1").arg(plugin->getName()));
        continue;
    }
    

    After that, my main UI opens and I open the plugin UI.
    When I click in the button that emit the sendMsg()...the main application crashs and gives me a console error at run-time

    libLobular-Bearing-Plugin.so: undefined symbol: _ZNK10Plugin_API7sendMsgE7QString8MSG_TYPES0_
    

    Why?
    How can I fix it?



  • @fem_dev First I would suggest you to a Q_OBJECT to your Plugin_API class header:

    class Plugin_API : public QObject
    {
        Q_OBJECT
    ...
    };  
    

    Then, other point, as @SGaist asked before, if you are running on Windows OS, you have to export the class to made it visible from outside and to be able to got access to this class.

    You have to do something like this:

    • modify the plugin project to add DEFINES += MYPLUGIN_LIBRARY
    • add export macro declaration in a header file (for example myplugin_macros.h)
    #include <QtCore/qglobal.h>
    
    #if defined(MYPLUGIN_LIBRARY)
    #  define MYPLUGIN_EXPORT Q_DECL_EXPORT
    #else
    #  define MYPLUGIN_EXPORT Q_DECL_IMPORT
    #endif
    
    • and modify again the class declaration a follow:
    #include "myplugin_macros.h"
    class MYPLUGIN_EXPORT Plugin_API : public QObject
    {
        Q_OBJECT
    ...
    };  
    

    Hope this could help you

    take a look at https://wiki.qt.io/How_to_create_a_library_with_Qt_and_use_it_in_an_application for more detailled explanation.


  • Lifetime Qt Champion

    Hi,

    Can you show your code ?

    How are you separating the plugin and the application ?



  • @SGaist I will explain better here...

    My goal is: send a signal from my plugin on_save_btn_clicked() Dialog event to my Main Application.

    Here is a simple diagram:
    Untitled Diagram (1).png
    plugin_qt_api.h:

    #ifndef PLUGIN_QT_API_H
    #define PLUGIN_QT_API_H
    
    #include <QObject>
    #include <QString>
    
    #include "message_types.h"
    
    class Plugin_API : public QObject
    {
    private:
       
    protected:
    
        void sendStatusMsg(const QString& msg) const;
    
    public:
        Plugin_API();
    
        virtual ~Plugin_API() = default;
    
    signals:
        void sendMsg(const QString source, const MSG_TYPE msgType, const QString msg) const;
    };
    // Declare our interface:
    Q_DECLARE_INTERFACE(Plugin_API, "com.rotortest.plugin")
    
    #endif // PLUGIN_QT_API_H
    
    

    plugin_qt_api.cpp:

    #include "plugin_qt_api.h"
    
    void Plugin_API::sendStatusMsg(const QString& msg) const {
        emit sendMsg("Plugin", MSG_TYPE::STATUS_MSG, msg);
    }
    

    dialog.h:

    #ifndef DIALOG_H
    #define DIALOG_H
    
    #include <QDialog>
    
    #include "plugin_qt_api.h"
    
    namespace Ui {
    class Dialog;
    }
    
    class Dialog : public QDialog 
    {
        Q_OBJECT
    
    public:
        explicit Dialog(QWidget *parent = nullptr);
        ~Dialog();
    
    private slots:
        void on_save_btn_clicked();
    
    private:
        Ui::Dialog *ui;
    };
    #endif // DIALOG_H
    

    dialog.cpp

    #include "dialog.h"
    #include "ui_dialog.h"
    
    Dialog::Dialog(QWidget *parent) :
        QDialog(parent),
        ui(new Ui::Dialog)
    {
        ui->setupUi(this);
    }
    
    Dialog::~Dialog()
    {
        delete ui;
    }
    
    void Dialog::on_save_btn_clicked()
    {
        emit sendStatusMsg("Ui Saved!");
    }
    

    So, what I have tried before:

    From Dialog::on_save_btn_clicked() method, emit a signal to the Plugin Class....and from this Plugin class I was sending the same data again to the Main App using another signal from Plugin to Main App.

    So...2 steps to send data from Dialog class to Main App.

    It compiles Ok...no errors, but gives me the error that I wrote here in the first post above.

    Now, my question is a little bit different:
    Is there a way to send a signal from the Dialog::on_save_btn_clicked() direct to the Main App?
    Obs.: May be I could #include plugin_qt_api.h in the dialog.h??

    How can I do it?

    Thanks!


  • Lifetime Qt Champion

    Are you on Windows ?



  • @fem_dev First I would suggest you to a Q_OBJECT to your Plugin_API class header:

    class Plugin_API : public QObject
    {
        Q_OBJECT
    ...
    };  
    

    Then, other point, as @SGaist asked before, if you are running on Windows OS, you have to export the class to made it visible from outside and to be able to got access to this class.

    You have to do something like this:

    • modify the plugin project to add DEFINES += MYPLUGIN_LIBRARY
    • add export macro declaration in a header file (for example myplugin_macros.h)
    #include <QtCore/qglobal.h>
    
    #if defined(MYPLUGIN_LIBRARY)
    #  define MYPLUGIN_EXPORT Q_DECL_EXPORT
    #else
    #  define MYPLUGIN_EXPORT Q_DECL_IMPORT
    #endif
    
    • and modify again the class declaration a follow:
    #include "myplugin_macros.h"
    class MYPLUGIN_EXPORT Plugin_API : public QObject
    {
        Q_OBJECT
    ...
    };  
    

    Hope this could help you

    take a look at https://wiki.qt.io/How_to_create_a_library_with_Qt_and_use_it_in_an_application for more detailled explanation.



  • @SGaist said in Signals Inheritance: undefined symbol:

    Are you on Windows ?

    No. I'm in Linux Ubuntu 20.04, but I will compile my Main App and my developed plugins in another OS: Windows 10 and Mac OSX.

    @KroMignon said in Signals Inheritance: undefined symbol:

    You have to do something like this:

    Thank you, I will do that!!

    Thank you guys!


Log in to reply