Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. how to communicate between plugin or app?
Qt 6.11 is out! See what's new in the release blog

how to communicate between plugin or app?

Scheduled Pinned Locked Moved Unsolved General and Desktop
21 Posts 5 Posters 3.4k Views 3 Watching
  • 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.
  • JianJianJ Offline
    JianJianJ Offline
    JianJian
    wrote on last edited by
    #4

    i get the same issue,and make me confuse

    C 1 Reply Last reply
    0
    • JianJianJ JianJian

      i get the same issue,and make me confuse

      C Offline
      C Offline
      ChrisW67
      wrote on last edited by
      #5

      @JianJian Which "same issue"?

      New-style connects (the only type you should be using in new code) are resolved entirely at build time:

      connect(iface,&_MyPlugin5::sigAdd,this,&MainWindow::onAdd,Qt::UniqueConnection); 
      

      This will compile if the appropriate header files are present, but fail to link because there is no corresponding link library containing a _MyPlugin5::sigAdd() exported symbol.

      That would be quite normal for a Qt plugin: they implement interfaces and instances created at run time are only driven through those interfaces. The main program and plugins are not directly linked to each other.

      Old-style connects are resolved at program run time:

      connect(iface,SIGNAL(sigAdd(QString)),this,SLOT(onAdd(QString)),Qt::UniqueConnection);
      

      This will compile and link just fine. At the time it is executed it might work if iface and this object contain the relevant signals and slots. If the objects do not have the named signals or slots then a runtime warning is output and the connect fails... the program will continue to run but not behave as expected.

      JianJianJ Pl45m4P 2 Replies Last reply
      0
      • C ChrisW67

        @JianJian Which "same issue"?

        New-style connects (the only type you should be using in new code) are resolved entirely at build time:

        connect(iface,&_MyPlugin5::sigAdd,this,&MainWindow::onAdd,Qt::UniqueConnection); 
        

        This will compile if the appropriate header files are present, but fail to link because there is no corresponding link library containing a _MyPlugin5::sigAdd() exported symbol.

        That would be quite normal for a Qt plugin: they implement interfaces and instances created at run time are only driven through those interfaces. The main program and plugins are not directly linked to each other.

        Old-style connects are resolved at program run time:

        connect(iface,SIGNAL(sigAdd(QString)),this,SLOT(onAdd(QString)),Qt::UniqueConnection);
        

        This will compile and link just fine. At the time it is executed it might work if iface and this object contain the relevant signals and slots. If the objects do not have the named signals or slots then a runtime warning is output and the connect fails... the program will continue to run but not behave as expected.

        JianJianJ Offline
        JianJianJ Offline
        JianJian
        wrote on last edited by
        #6

        @ChrisW67 "the same issue" is use New-style connects will get the error "undefined reference to 'xxxx::staticMetaObject'" and function symbol error,but if i use the Old-style connects ,every thing is ok

        SGaistS 1 Reply Last reply
        0
        • JianJianJ JianJian

          @ChrisW67 "the same issue" is use New-style connects will get the error "undefined reference to 'xxxx::staticMetaObject'" and function symbol error,but if i use the Old-style connects ,every thing is ok

          SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #7

          @JianJian do you have a library that defines the plugin interface and link the main application and the plugin to it ?

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

          JianJianJ 1 Reply Last reply
          0
          • SGaistS SGaist

            @JianJian do you have a library that defines the plugin interface and link the main application and the plugin to it ?

            JianJianJ Offline
            JianJianJ Offline
            JianJian
            wrote on last edited by
            #8

            @SGaist yes i do have the interface

            // interface.h header
            class BasePluginInterface
            {
            public:
                explicit BasePluginInterface();
                virtual ~BasePluginInterface();
                virtual BasePluginInterface* plugin() = 0;
                virtual BasePluginInterface* newPlugin() = 0;
            
            };
            
            #define BasePluginInterface_iid "QtPluginDemo.QPlugins.BasePluginInterface"
            Q_DECLARE_INTERFACE(BasePluginInterface, BasePluginInterface_iid)
            
            // qlogshowplugin.h header
            #include "BasePluginInterface.h"
            class QLogShowPluginInterface
            {
            public:
                //explicit QLogShowPluginInterface(QWidget* parent = nullptr);
                virtual ~QLogShowPluginInterface();
                virtual int add(int a, int b) = 0;
                //signals: not work this way
                //virtual void sig_msg(QString) = 0;
                // slots
               //public slots:
                virtual void slot_showMsg(QString msg) = 0;
            };
            
            #define QLogShowPluginInterface_iid "QtPluginDemo.plugins.QLogShowPluginInterface"
            Q_DECLARE_INTERFACE(QLogShowPluginInterface, QLogShowPluginInterface_iid)
            
            class  QLogShow_Plugin : public QWidget, public QLogShowPluginInterface, public BasePluginInterface
            {
                Q_OBJECT
                Q_PLUGIN_METADATA(IID "qtPluginDemo.plugins.QLogShowPlugin")
            
                Q_INTERFACES(BasePluginInterface QLogShowPluginInterface)
            
            public:
                explicit QLogShow_Plugin(QWidget* parent = nullptr);
                ~QLogShow_Plugin();
                QLogShow_Plugin* plugin() ;
                QLogShow_Plugin* newPlugin() ;
                int add(int a, int b) ;
            public slots:
                void slot_showMsg(QString msg);
            signals:
                void sig_msg(QString);
            
            private slots:
                void on_pb_msg_clicked();
            
            private:
                Ui::QLogShow_Plugin *ui;
            };
            
            the plugin .pro file
            QT       += core gui
            
            greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
            
            CONFIG += c++11
            TARGET = QLogShow_Plugin
            TEMPLATE = lib
            CONFIG += plugin
            //the other content....
            

            and i use the plugin in another dll ,in the same application

            // plugin magr dll
            QT       += core gui
            
            greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
            
            CONFIG += c++11
            TARGET =  QPluginMagr
            TEMPLATE = lib
            DEFINES += $${upper($$member(TARGET))}_LIBRARY
            

            the plugin magr cpp file,use plugin

            #include "QLogShow_Plugin.h"
            QPluginLoader loader(path);
                    QObject* plugin = loader.instance();
                    if(!plugin){
                     return;
                    }
                    p = qobject_cast<BasePluginInterface*>(plugin);
                    if(p == nullptr){
                        return;
                    } else {
                        auto plug = static_cast<QLogShow_Plugin*>(p);
                    // show error undefined reference to `QLogShow_Plugin::staticMetaObject'
                      connect(plug, &QLogShow_Plugin::sig_msg, [](){}); // error
                    }
            
            1 Reply Last reply
            0
            • C ChrisW67

              @JianJian Which "same issue"?

              New-style connects (the only type you should be using in new code) are resolved entirely at build time:

              connect(iface,&_MyPlugin5::sigAdd,this,&MainWindow::onAdd,Qt::UniqueConnection); 
              

              This will compile if the appropriate header files are present, but fail to link because there is no corresponding link library containing a _MyPlugin5::sigAdd() exported symbol.

              That would be quite normal for a Qt plugin: they implement interfaces and instances created at run time are only driven through those interfaces. The main program and plugins are not directly linked to each other.

              Old-style connects are resolved at program run time:

              connect(iface,SIGNAL(sigAdd(QString)),this,SLOT(onAdd(QString)),Qt::UniqueConnection);
              

              This will compile and link just fine. At the time it is executed it might work if iface and this object contain the relevant signals and slots. If the objects do not have the named signals or slots then a runtime warning is output and the connect fails... the program will continue to run but not behave as expected.

              Pl45m4P Offline
              Pl45m4P Offline
              Pl45m4
              wrote on last edited by
              #9

              @ChrisW67 said in how to communicate between plugin or app?:

              New-style connects (the only type you should be using in new code)

              Internally there are still a lot of string-based connection in Qt, which you also have to face when Qt pImpl style to create your own widgets from scratch.
              See, Q_PRIVATE_SLOT for example.


              If debugging is the process of removing software bugs, then programming must be the process of putting them in.

              ~E. W. Dijkstra

              JianJianJ 1 Reply Last reply
              0
              • Pl45m4P Pl45m4

                @ChrisW67 said in how to communicate between plugin or app?:

                New-style connects (the only type you should be using in new code)

                Internally there are still a lot of string-based connection in Qt, which you also have to face when Qt pImpl style to create your own widgets from scratch.
                See, Q_PRIVATE_SLOT for example.

                JianJianJ Offline
                JianJianJ Offline
                JianJian
                wrote on last edited by
                #10

                @Pl45m4 that means i have to use the Old-style connects to connect the signals

                C 1 Reply Last reply
                0
                • JianJianJ JianJian

                  @Pl45m4 that means i have to use the Old-style connects to connect the signals

                  C Offline
                  C Offline
                  ChrisW67
                  wrote on last edited by
                  #11

                  @JianJian No, it does not. It does mean you need to organise your project a bit differently.

                  Here is a complete example: https://github.com/ChrisW67/qtforum-pluginplay
                  It works by creating a library containing the interfaces (abstract base classes) that is used by the application and the plugins. The application does not know of the specific plugin classes, only the interface classes. The application connects objects from the plugins using the interface. Neither plugin knows anything about the other or the application.

                  There is probably more than one (neater) way to achieve this.

                  JianJianJ 2 Replies Last reply
                  0
                  • C ChrisW67

                    @JianJian No, it does not. It does mean you need to organise your project a bit differently.

                    Here is a complete example: https://github.com/ChrisW67/qtforum-pluginplay
                    It works by creating a library containing the interfaces (abstract base classes) that is used by the application and the plugins. The application does not know of the specific plugin classes, only the interface classes. The application connects objects from the plugins using the interface. Neither plugin knows anything about the other or the application.

                    There is probably more than one (neater) way to achieve this.

                    JianJianJ Offline
                    JianJianJ Offline
                    JianJian
                    wrote on last edited by
                    #12

                    @ChrisW67 thanks for your reply, i use qmake, and the most important is that i use plugin because i really do not want to add library import in my pro file, so i can also compile my application without plugin lib/dll.
                    i have learned your code,it seems needs to add lib import in cmake file, i think it will have compile error if i have no plugin dll in my application.

                    C 1 Reply Last reply
                    0
                    • JianJianJ JianJian

                      @ChrisW67 thanks for your reply, i use qmake, and the most important is that i use plugin because i really do not want to add library import in my pro file, so i can also compile my application without plugin lib/dll.
                      i have learned your code,it seems needs to add lib import in cmake file, i think it will have compile error if i have no plugin dll in my application.

                      C Offline
                      C Offline
                      ChrisW67
                      wrote on last edited by ChrisW67
                      #13

                      @JianJian said in how to communicate between plugin or app?:

                      I use qmake

                      All of this works with qmake. CMake and qmake just coordinate building the project and do not change the behaviour.

                      I have added qmake project files to the example. I also removed some stray files from the app directory.

                      i think it will have compile error if i have no plugin dll in my application.

                      No. The application requires the static library containing a skeleton interface. It does not require any of the actual dynamically loaded plugins to build. Try removing the src/plugins directory from the top-level PRO file and do a clean build.

                      1 Reply Last reply
                      0
                      • SGaistS Offline
                        SGaistS Offline
                        SGaist
                        Lifetime Qt Champion
                        wrote on last edited by
                        #14

                        In addition to @ChrisW67, if memory serves well, the library that is common to the plugins and the application shall not be static as it will result in duplicated static meta objects being loaded and will cause trouble.

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

                        C 1 Reply Last reply
                        1
                        • SGaistS SGaist

                          In addition to @ChrisW67, if memory serves well, the library that is common to the plugins and the application shall not be static as it will result in duplicated static meta objects being loaded and will cause trouble.

                          C Offline
                          C Offline
                          ChrisW67
                          wrote on last edited by
                          #15

                          @SGaist You are probably right. I did not see problems, but it was a trivial usage. No reason it cannot be a shared library.

                          1 Reply Last reply
                          0
                          • C ChrisW67

                            @JianJian No, it does not. It does mean you need to organise your project a bit differently.

                            Here is a complete example: https://github.com/ChrisW67/qtforum-pluginplay
                            It works by creating a library containing the interfaces (abstract base classes) that is used by the application and the plugins. The application does not know of the specific plugin classes, only the interface classes. The application connects objects from the plugins using the interface. Neither plugin knows anything about the other or the application.

                            There is probably more than one (neater) way to achieve this.

                            JianJianJ Offline
                            JianJianJ Offline
                            JianJian
                            wrote on last edited by
                            #16

                            @ChrisW67 i have code like your way,and it still not work,this is my code: [https://github.com/xiaobingcaicai/qtpluginplay-demo],
                            1.uncheck the shadow build
                            2.compile the plugins sub-project
                            3.compile the app sub-project
                            show the error "undefined reference to `SenderInterface::staticMetaObject'"

                            C 1 Reply Last reply
                            0
                            • JianJianJ JianJian

                              @ChrisW67 i have code like your way,and it still not work,this is my code: [https://github.com/xiaobingcaicai/qtpluginplay-demo],
                              1.uncheck the shadow build
                              2.compile the plugins sub-project
                              3.compile the app sub-project
                              show the error "undefined reference to `SenderInterface::staticMetaObject'"

                              C Offline
                              C Offline
                              ChrisW67
                              wrote on last edited by
                              #17

                              No need to build the sub-projects independently: just build the top level and it will recurse into the subdirectories.

                              • PluginPlay project should build everything in order but:
                                • you are not building sub-project interfaces (commented out, and missing).
                                • you have omitted the CONFIG setting for ordered building (there are other ways to ensure the correct order but this is simplest)
                              • Sub-project app depends on interfaces and so is unsatisfied.
                              • Sub-project plugins depend on interfaces.

                              The interfaces library needs to be independent of both app and plugins: you have wedged it into plugins.

                              JianJianJ 1 Reply Last reply
                              1
                              • C ChrisW67

                                No need to build the sub-projects independently: just build the top level and it will recurse into the subdirectories.

                                • PluginPlay project should build everything in order but:
                                  • you are not building sub-project interfaces (commented out, and missing).
                                  • you have omitted the CONFIG setting for ordered building (there are other ways to ensure the correct order but this is simplest)
                                • Sub-project app depends on interfaces and so is unsatisfied.
                                • Sub-project plugins depend on interfaces.

                                The interfaces library needs to be independent of both app and plugins: you have wedged it into plugins.

                                JianJianJ Offline
                                JianJianJ Offline
                                JianJian
                                wrote on last edited by
                                #18

                                @ChrisW67 i have also tested the way you said:The interfaces library needs to be independent of both app and plugins. still get same error.
                                i think the primary cause is the plugin is not imported in the pro file, so the signs symbol can not be reconized, but if i import the plugin in the pro,the app can not compile success if there is no pugin(.dll/.so) file

                                maybe i have also maked other mistakes 😂😂

                                C 1 Reply Last reply
                                0
                                • JianJianJ JianJian

                                  @ChrisW67 i have also tested the way you said:The interfaces library needs to be independent of both app and plugins. still get same error.
                                  i think the primary cause is the plugin is not imported in the pro file, so the signs symbol can not be reconized, but if i import the plugin in the pro,the app can not compile success if there is no pugin(.dll/.so) file

                                  maybe i have also maked other mistakes 😂😂

                                  C Offline
                                  C Offline
                                  ChrisW67
                                  wrote on last edited by
                                  #19

                                  @JianJian Yes, look more closely at my example on GitHub.

                                  The app does not need to link to, or include headers from, the plugin(s). The app only needs to know about the interface and the minimal link library it produces.

                                  JianJianJ 1 Reply Last reply
                                  0
                                  • C ChrisW67

                                    @JianJian Yes, look more closely at my example on GitHub.

                                    The app does not need to link to, or include headers from, the plugin(s). The app only needs to know about the interface and the minimal link library it produces.

                                    JianJianJ Offline
                                    JianJianJ Offline
                                    JianJian
                                    wrote on last edited by
                                    #20

                                    @ChrisW67 the minimal link library you mean is the .a/.lib library file?

                                    C 1 Reply Last reply
                                    0
                                    • JianJianJ JianJian

                                      @ChrisW67 the minimal link library you mean is the .a/.lib library file?

                                      C Offline
                                      C Offline
                                      ChrisW67
                                      wrote on last edited by ChrisW67
                                      #21

                                      Yes, the libinterfaces.a or equivalent depending on compiler.

                                      I have modified the Git sources to make this library shared rather than static. So, on Linux you get:

                                      .../src/interfaces/libinterfaces.so  # both the link and runtime library
                                      

                                      on Windows you get (from memory):

                                      .../src/interfaces/libinterfaces.a     # MinGW the link library
                                      .../src/interfaces/libinterfaces.lib   # MSVC the link library
                                      .../src/interfaces/libinterfaces.dll   # the runtime library
                                      

                                      On my Linux box the resulting app executable is linked to these things at run time:

                                      $ ls .
                                      app  libbasicreceiver.so  libbasicsender.so  libinterfaces.so
                                      $ ldd app  # the application with no direct linkage to a plugin
                                              linux-vdso.so.1 (0x00007fff1819c000)
                                              libinterfaces.so => ./libinterfaces.so (0x0000718c2b36f000)
                                              ...
                                      $ ldd libbasicreceiver.so  # a plugin
                                              linux-vdso.so.1 (0x00007ffdc8fe8000)
                                              libinterfaces.so => ./libinterfaces.so (0x000070653e942000)
                                              ...
                                      
                                      1 Reply Last reply
                                      1

                                      • Login

                                      • Login or register to search.
                                      • First post
                                        Last post
                                      0
                                      • Categories
                                      • Recent
                                      • Tags
                                      • Popular
                                      • Users
                                      • Groups
                                      • Search
                                      • Get Qt Extensions
                                      • Unsolved