Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Update: Forum Guidelines & Code of Conduct

    Solved Signals Inheritance: undefined symbol

    General and Desktop
    3
    6
    321
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • F
      fem_dev last edited by

      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?

      1 Reply Last reply Reply Quote 0
      • KroMignon
        KroMignon @fem_dev last edited by KroMignon

        @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.

        It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

        1 Reply Last reply Reply Quote 3
        • SGaist
          SGaist Lifetime Qt Champion last edited by

          Hi,

          Can you show your code ?

          How are you separating the plugin and the application ?

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          F 1 Reply Last reply Reply Quote 0
          • F
            fem_dev @SGaist last edited by fem_dev

            @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!

            KroMignon 1 Reply Last reply Reply Quote 0
            • SGaist
              SGaist Lifetime Qt Champion last edited by

              Are you on Windows ?

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              F 1 Reply Last reply Reply Quote 0
              • KroMignon
                KroMignon @fem_dev last edited by KroMignon

                @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.

                It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                1 Reply Last reply Reply Quote 3
                • F
                  fem_dev @SGaist last edited by

                  @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!

                  1 Reply Last reply Reply Quote 0
                  • First post
                    Last post