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. connect: External "C" function

connect: External "C" function

Scheduled Pinned Locked Moved Solved General and Desktop
16 Posts 4 Posters 1.8k Views
  • 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 Offline
    F Offline
    fem_dev
    wrote on 3 Aug 2020, 21:19 last edited by
    #1

    I developed a Qt GUI C++ shared library (plugin) that contains a Fortran 90 static library inside of it.

    To enable to receive the Fortran data back to C++ side, I created a Fortran/C++ interface and it works great.

    In the C++ side I have:

    external "C" {
        void callFortran(...input arguments ....);
        void fortranMsg(int msgType, char* msg);
    }
    

    So, when Fortran send a message to C++, I already receive that inside of this external C function below:

    void fortranMsg(int msgType, char* msg)
    {
        // Messages from Fortran subroutine to C++ side
        // It is already working!
    }
    

    I would like to connect this fortranMsg() function to a plugin method, like:

    Plugin::Plugin(QObject* parent)
    {
        // WRONG SINTAX: JUST A EXAMPLE
        bool conn = connect(fortranMsg, this, &Plugin::receivedMsg);
    }
    
    Plugin::receivedMsg(int msgType, char* msg)
    {
        // Get that Fortran message inside a plugin method
    }
    

    I don't know if connect is a good way to do that...it is just an example of what I need to do...

    How can I send the data (msgType and msg) from fortranMsg() to a Plugin::receivedMsg()?

    Thank you,

    J 1 Reply Last reply 3 Aug 2020, 23:59
    0
    • F fem_dev
      13 Aug 2020, 15:11

      @jsulm thank you...I'm almost there...
      Here are my modifications:

      Here is my plugin.h header file:

      #include "dialog.h"
      #include "plugin_global.h"
      #include "plugin_qt_api.h"
      
      extern Plugin_API *pluginInstance; // FIRST MODIFICATION
      
      // Fortran interface
      extern "C" {
          void fortranMsg(int msgType, char* msg);
      }
      
      class PLUGIN_EXPORT Plugin : public Plugin_API
      {
          Q_OBJECT
          Q_PLUGIN_METADATA(IID "com.rotortest.plugin")
          Q_INTERFACES(Plugin_API)
      
      private:
          Dialog _ui;
      
      public:
      
          explicit Plugin(QObject* parent = nullptr);
          ~Plugin();
      
          ...
      }
      

      Here is my plugin.cpp implementation file:

      #include "plugin.h"
      #include <iostream>
      
      #include "dialog.h"
      
      Plugin_API* pluginInstance = nullptr; // SECOND MODIFICATION
      
      Plugin::Plugin(QObject* parent)
      {
          Q_UNUSED(parent)
      }
      
      // Other Plugin method implementations...
      

      And inside the plugin.cpp I have:

      void fortranMsg(int msgType, char* msg)
      {
          std::cout << msgType << " | " << msg << std::endl; // PRINT THE MSG IN THE Qt CONSOLE OK
      
          if (pluginInstance) {
              pluginInstance->sendStatusMsg(QString(msg));
          } else {
              std::cout << "pluginInstance is NULL" << std::endl; // ALWAYS NULLPTR
          }
      }
      

      I do NOT declared `pluginInstance` in my `main application` // LAST MODIFICATION
      

      I got a clean build. No errors, no warnings! All good!
      And I don't got any run-time erros, BUT I got always the same console message:

      pluginInstance is NULL
      

      After that, I tried too:

      Plugin_API* pluginInstance = nullptr; // SECOND MODIFICATION
      
      Plugin::Plugin(QObject* parent)
      {
          Q_UNUSED(parent)
          
          pluginInstance = new Plugin; // CREATE A VALID INSTANCE
      }
      

      In this case, the pluginInstance is NULL console message disapears (the pointer is valid), BUT it is not calling correctly the Plugin::sendStatusMsg() method as I want.
      So, I don't know why, I don't get the sent plugin message in my main application.

      @JKSH here is how I communicate my own Plugin with my main application:
      First, the plugin_qt_api.h:

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

      Second, the plugin.h:

      #include "plugin_global.h"
      #include "plugin_qt_api.h"
      
      extern Plugin_API *pluginInstance;
      
      // Fortran subroutines
      extern "C" {
          void fortranMsg(int msgType, char* msg);
      }
      
      class PLUGIN_EXPORT Plugin : public Plugin_API
      {
          Q_OBJECT
          Q_PLUGIN_METADATA(IID "com.rotortest.plugin")
          Q_INTERFACES(Plugin_API)
      
      public:
      
          explicit Plugin(QObject* parent = nullptr);
      
          ~Plugin();
      
          ...
          void sendStatusMsg(const QString &msg) override;
      };
      

      Finally, the Plugin::sendStatusMsg() method implementation inside the plugin.cpp file:

      void Plugin::sendStatusMsg(const QString& msg) {
          emit sendMsg("My Plugin", MSG_TYPE::STATUS_MSG, msg);
      }
      

      This plugin method works good if I call it from a method inside the Plugin class. No problems here!
      My problem is ONLY when I have to call this method from the fortranMsg() function. Because it is a function and NOT a Plugin method.

      So, when my Fortran send a message to the C++ side, I got the message correctly in the fortranMsg() function (I can see it on Qt console), but I don't know how to pass this received message to the Plugin::sendStatusMsg() method.

      I want to do that to enable my plugins always use the same plugin method to send messages from the plugin side to my main application.

      As you can see above, inside my main application, I have a method called App::loadPlugin().
      Inside of it, I have:

      @fem_dev said in connect: External "C" function:

      bool conn1 = connect(plugin, &Plugin_API::sendMsg, this, &App::receivedMsg);

      Could you help me?

      F Offline
      F Offline
      fem_dev
      wrote on 15 Aug 2020, 22:06 last edited by fem_dev
      #12

      @fem_dev Thank you @JKSH @jsulm and @JonB for all help in this topic! I really need to say "thank you"! You all are great!

      With your help I finally solve this problem.

      Here is my plugin.h header file:

      extern Plugin_API *pluginInstance; // <-- 1. CREATE A GLOBAL INTERFACE CLASS POINTER
      
      extern "C" {
          void fortranMsg(int msgType, char* msg);
      }
      
      class PLUGIN_EXPORT Plugin : public Plugin_API
      {
          Q_OBJECT
          Q_PLUGIN_METADATA(IID "com.rotortest.plugin")
          Q_INTERFACES(Plugin_API)
      
      public: 
          ...
          void sendStatusMsg(const QString &msg) override;
      }
      

      Here is my plugin.cpp implementation file:

      Plugin_API* pluginInstance = nullptr; // <-- 2. Init the global pointer to nullptr
      
      Plugin::Plugin(QObject* parent)
      {
          pluginInstance = this; // <-- 3. Point to the current object
      }
      

      Now, I can use the global variable pluginInstance inside a pure function too.
      With this pointer, I can call any Plugin method from any pure function. Like:

      void fortranMsg(int msgType, char* msg)
      {
          pluginInstance->sendStatusMsg(QString(msg));    
      }
      

      That's it!

      Thank you all again!

      1 Reply Last reply
      1
      • F fem_dev
        3 Aug 2020, 21:19

        I developed a Qt GUI C++ shared library (plugin) that contains a Fortran 90 static library inside of it.

        To enable to receive the Fortran data back to C++ side, I created a Fortran/C++ interface and it works great.

        In the C++ side I have:

        external "C" {
            void callFortran(...input arguments ....);
            void fortranMsg(int msgType, char* msg);
        }
        

        So, when Fortran send a message to C++, I already receive that inside of this external C function below:

        void fortranMsg(int msgType, char* msg)
        {
            // Messages from Fortran subroutine to C++ side
            // It is already working!
        }
        

        I would like to connect this fortranMsg() function to a plugin method, like:

        Plugin::Plugin(QObject* parent)
        {
            // WRONG SINTAX: JUST A EXAMPLE
            bool conn = connect(fortranMsg, this, &Plugin::receivedMsg);
        }
        
        Plugin::receivedMsg(int msgType, char* msg)
        {
            // Get that Fortran message inside a plugin method
        }
        

        I don't know if connect is a good way to do that...it is just an example of what I need to do...

        How can I send the data (msgType and msg) from fortranMsg() to a Plugin::receivedMsg()?

        Thank you,

        J Offline
        J Offline
        JKSH
        Moderators
        wrote on 3 Aug 2020, 23:59 last edited by
        #2

        @fem_dev said in connect: External "C" function:

        How can I send the data (msgType and msg) from fortranMsg() to a Plugin::receivedMsg()?

        Since fortranMsg() is a function that is called by Fortran, you cannot connect it like a signal. Instead, you must add extra code inside fortranMsg():

        void fortranMsg(int msgType, char* msg)
        {
            // Messages from Fortran subroutine to C++ side
            // It is already working!
        
            exportData(msgType, msg); // <-- Add a function call here to pass the data out
        }
        

        There are many ways you could implement the exporting function. For example, you could store a pointer to the plugin object as a global variable and call receivedMsg() directly:

        Plugin *pluginInstance = nullptr; // This pointer can be updated when you construct your plugin object
        
        void fortranMsg(int msgType, char* msg)
        {
            // Messages from Fortran subroutine to C++ side
            // It is already working!
        
            if (pluginInstance)
                 pluginInstsance->receivedMsg(msgType, msg);
        }
        

        Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

        F 1 Reply Last reply 4 Aug 2020, 01:16
        6
        • J JKSH
          3 Aug 2020, 23:59

          @fem_dev said in connect: External "C" function:

          How can I send the data (msgType and msg) from fortranMsg() to a Plugin::receivedMsg()?

          Since fortranMsg() is a function that is called by Fortran, you cannot connect it like a signal. Instead, you must add extra code inside fortranMsg():

          void fortranMsg(int msgType, char* msg)
          {
              // Messages from Fortran subroutine to C++ side
              // It is already working!
          
              exportData(msgType, msg); // <-- Add a function call here to pass the data out
          }
          

          There are many ways you could implement the exporting function. For example, you could store a pointer to the plugin object as a global variable and call receivedMsg() directly:

          Plugin *pluginInstance = nullptr; // This pointer can be updated when you construct your plugin object
          
          void fortranMsg(int msgType, char* msg)
          {
              // Messages from Fortran subroutine to C++ side
              // It is already working!
          
              if (pluginInstance)
                   pluginInstsance->receivedMsg(msgType, msg);
          }
          
          F Offline
          F Offline
          fem_dev
          wrote on 4 Aug 2020, 01:16 last edited by
          #3

          Thank you @JKSH for your quick response...

          @JKSH said in connect: External "C" function:

          There are many ways you could implement the exporting function.

          I think that I need some help to understand in which scope should I write this lines...

          The problem is: Only inside the main application I can write something like this:

          Plugin *pluginInstance = nullptr; // This pointer can be updated when you construct your plugin object
          

          Because each plugin is loaded by the main application using QPluginLoader.
          So, I think that I can't use this line above inside the Plugin class. Am I right?

          Here is my plugin.h header file:

          #include "dialog.h"
          #include "plugin_global.h"
          #include "plugin_qt_api.h"
          
          // Fortran subroutines
          extern "C" {
              void callFortran(...input arguments ....);
              void fortranMsg(int msgType, char* msg);
          }
          
          class PLUGIN_EXPORT Plugin : public Plugin_API
          {
              Q_OBJECT
              Q_PLUGIN_METADATA(IID "com.rotortest.plugin")
              Q_INTERFACES(Plugin_API)
          
          private:
              Dialog _ui;
          
          public:
          
              explicit Plugin(QObject* parent = nullptr);
              ~Plugin();
          
              //... All Methods override
          
              void receiveMsg(int msgType, char* msg);
          };
          

          Here is my plugin.cpp implementation:

          #include <iostream>
          #include "plugin.h"
          #include "dialog.h"
          
          Plugin::Plugin(QObject* parent)
          {
          }
          
          Plugin::~Plugin()
          {
          }
          
          void Plugin::receivedMsg(int msgType, char* msg)
          {
          
          }
          
          void fortranMsg(int msgType, char* msg)
          {
              std::cout << msgType << " | " << msg << std::endl;
          
              // SEND DATA TO A PLUGIN METHOD
              // HOW?
          }
          

          Could you help me pass this data from the fortranMsg () function to the Plugin :: receivedMsg () method?

          A first thought that comes to mind is that I should try to make this connection entirely within the shared library (plugin) project, without resorting to the main application project.
          Or is there a better way to "connect" via the main application?

          jsulmJ J 2 Replies Last reply 4 Aug 2020, 04:19
          0
          • F fem_dev
            4 Aug 2020, 01:16

            Thank you @JKSH for your quick response...

            @JKSH said in connect: External "C" function:

            There are many ways you could implement the exporting function.

            I think that I need some help to understand in which scope should I write this lines...

            The problem is: Only inside the main application I can write something like this:

            Plugin *pluginInstance = nullptr; // This pointer can be updated when you construct your plugin object
            

            Because each plugin is loaded by the main application using QPluginLoader.
            So, I think that I can't use this line above inside the Plugin class. Am I right?

            Here is my plugin.h header file:

            #include "dialog.h"
            #include "plugin_global.h"
            #include "plugin_qt_api.h"
            
            // Fortran subroutines
            extern "C" {
                void callFortran(...input arguments ....);
                void fortranMsg(int msgType, char* msg);
            }
            
            class PLUGIN_EXPORT Plugin : public Plugin_API
            {
                Q_OBJECT
                Q_PLUGIN_METADATA(IID "com.rotortest.plugin")
                Q_INTERFACES(Plugin_API)
            
            private:
                Dialog _ui;
            
            public:
            
                explicit Plugin(QObject* parent = nullptr);
                ~Plugin();
            
                //... All Methods override
            
                void receiveMsg(int msgType, char* msg);
            };
            

            Here is my plugin.cpp implementation:

            #include <iostream>
            #include "plugin.h"
            #include "dialog.h"
            
            Plugin::Plugin(QObject* parent)
            {
            }
            
            Plugin::~Plugin()
            {
            }
            
            void Plugin::receivedMsg(int msgType, char* msg)
            {
            
            }
            
            void fortranMsg(int msgType, char* msg)
            {
                std::cout << msgType << " | " << msg << std::endl;
            
                // SEND DATA TO A PLUGIN METHOD
                // HOW?
            }
            

            Could you help me pass this data from the fortranMsg () function to the Plugin :: receivedMsg () method?

            A first thought that comes to mind is that I should try to make this connection entirely within the shared library (plugin) project, without resorting to the main application project.
            Or is there a better way to "connect" via the main application?

            jsulmJ Offline
            jsulmJ Offline
            jsulm
            Lifetime Qt Champion
            wrote on 4 Aug 2020, 04:19 last edited by
            #4

            @fem_dev said in connect: External "C" function:

            // SEND DATA TO A PLUGIN METHOD
            // HOW?

            Like @JKSH suggested.
            Add a header file and put

            extern Plugin *pluginInstance;
            

            there. Then define pluginInstance in one of your cpp files (main.cpp for example). Include the header file in the cpp file where you define fortranMsg() and you can call pluginInstance as suggested.

            https://forum.qt.io/topic/113070/qt-code-of-conduct

            F 1 Reply Last reply 4 Aug 2020, 14:35
            1
            • jsulmJ jsulm
              4 Aug 2020, 04:19

              @fem_dev said in connect: External "C" function:

              // SEND DATA TO A PLUGIN METHOD
              // HOW?

              Like @JKSH suggested.
              Add a header file and put

              extern Plugin *pluginInstance;
              

              there. Then define pluginInstance in one of your cpp files (main.cpp for example). Include the header file in the cpp file where you define fortranMsg() and you can call pluginInstance as suggested.

              F Offline
              F Offline
              fem_dev
              wrote on 4 Aug 2020, 14:35 last edited by
              #5

              @jsulm Thank you...I'm almost there...

              Here is what I did:

              #include <iostream>
              #include "plugin.h"
              #include "dialog.h"
              
              extern Plugin *pluginInstance;
              
              Plugin::Plugin(QObject* parent)
              {
              }
              
              void Plugin::receivedMsg(int msgType, char* msg)
              {
              }
              
              void fortranMsg(int msgType, char* msg)
              {
                  std::cout << msgType << " | " << msg << std::endl;
              
                  if (pluginInstance)
                       pluginInstance->receivedMsg(msgType, msg);
              }
              

              The shared library (plugin) compiles without any error or warning. All ok!

              But when my main application tries to load this shared library (using QPluginLoader) I got this run-time error:

              Cannot load library libLobular-Bearing.so: undefined symbol: pluginInstance
              

              What is missing? How can I fix it?

              Thank you,

              JonBJ 1 Reply Last reply 4 Aug 2020, 19:44
              0
              • F fem_dev
                4 Aug 2020, 14:35

                @jsulm Thank you...I'm almost there...

                Here is what I did:

                #include <iostream>
                #include "plugin.h"
                #include "dialog.h"
                
                extern Plugin *pluginInstance;
                
                Plugin::Plugin(QObject* parent)
                {
                }
                
                void Plugin::receivedMsg(int msgType, char* msg)
                {
                }
                
                void fortranMsg(int msgType, char* msg)
                {
                    std::cout << msgType << " | " << msg << std::endl;
                
                    if (pluginInstance)
                         pluginInstance->receivedMsg(msgType, msg);
                }
                

                The shared library (plugin) compiles without any error or warning. All ok!

                But when my main application tries to load this shared library (using QPluginLoader) I got this run-time error:

                Cannot load library libLobular-Bearing.so: undefined symbol: pluginInstance
                

                What is missing? How can I fix it?

                Thank you,

                JonBJ Online
                JonBJ Online
                JonB
                wrote on 4 Aug 2020, 19:44 last edited by JonB 8 Apr 2020, 20:00
                #6

                @fem_dev
                You are missing where @jsulm / @JKSH said:

                Then define pluginInstance in one of your cpp files (main.cpp for example)

                You need the line reading

                Plugin *pluginInstance = nullptr; // This pointer can be updated when you construct your plugin object
                

                in your main application. Once, in one of its .cpp files.. Note that is without the extern. Where do you have this?

                Explanation:

                Your shared library has extern Plugin *pluginInstance; in it. That means it says "there is/must be a pluginInstance out there, which I can use". That is what extern means. So it compiles.

                When you come to load at run-time, your program needs to have defined this pluginInstance, to provide this variable. Without it you get undefined symbol. The statement Plugin *pluginInstance, without the extern, defines the symbol. That is needed in some one (and only one) .cpp file of the main application loading your shared library.

                F 1 Reply Last reply 4 Aug 2020, 21:33
                3
                • JonBJ JonB
                  4 Aug 2020, 19:44

                  @fem_dev
                  You are missing where @jsulm / @JKSH said:

                  Then define pluginInstance in one of your cpp files (main.cpp for example)

                  You need the line reading

                  Plugin *pluginInstance = nullptr; // This pointer can be updated when you construct your plugin object
                  

                  in your main application. Once, in one of its .cpp files.. Note that is without the extern. Where do you have this?

                  Explanation:

                  Your shared library has extern Plugin *pluginInstance; in it. That means it says "there is/must be a pluginInstance out there, which I can use". That is what extern means. So it compiles.

                  When you come to load at run-time, your program needs to have defined this pluginInstance, to provide this variable. Without it you get undefined symbol. The statement Plugin *pluginInstance, without the extern, defines the symbol. That is needed in some one (and only one) .cpp file of the main application loading your shared library.

                  F Offline
                  F Offline
                  fem_dev
                  wrote on 4 Aug 2020, 21:33 last edited by
                  #7

                  @JonB Almost there...

                  My shared library (plugin) have a Interface Class called Plugin_API as you can see below:

                  class PLUGIN_EXPORT Plugin : public Plugin_API
                  {
                      Q_OBJECT
                      Q_PLUGIN_METADATA(IID "com.rotortest.plugin")
                      Q_INTERFACES(Plugin_API)
                  ...
                  }
                  

                  So, inside my main application I have the same Plugin_API Interface...not the Plugin class.
                  I think that the extern variable declaration must be PluginAPI type in both Qt projects (plugin and main application), right?

                  #include <iostream>
                  #include "plugin.h"
                  #include "dialog.h"
                  
                  extern Plugin_API *pluginInstance; // Changed from 'Plugin' to 'Plugin_API'
                  
                  Plugin::Plugin(QObject* parent)
                  {
                  }
                  
                  void Plugin::receivedMsg(int msgType, char* msg)
                  {
                  }
                  
                  void fortranMsg(int msgType, char* msg)
                  {
                      std::cout << msgType << " | " << msg << std::endl;
                  
                      if (pluginInstance)
                           pluginInstance->receivedMsg(msgType, msg);
                  }
                  

                  In my main application project, I opened the main GUI window Widget (called: App.cpp) and tried to add this line below:

                  #include "app.h"
                  #include "ui_app.h"
                  
                  Plugin_API *pluginInstance = nullptr;
                  
                  App::App(QWidget *parent)
                      : QMainWindow(parent)
                      , ui(new Ui::App)
                  {
                      ui->setupUi(this);
                  ...
                  }
                  

                  But I got the same run time error:

                  libLobular-Bearing.so: undefined symbol: pluginInstance
                  

                  I tried to change the pointer value inside the App:loadPlugins() method (as you can see below) but without success too.

                  void App::loadPlugins(const QStringList pluginsList)
                  {
                      foreach(QString file, pluginsList) {
                  
                          QPluginLoader loader(file);
                  
                          // Error checking:
                          if (!loader.load()) {
                              sendErrorMsg(tr("%1: ").arg(loader.errorString()));
                              continue;
                          }
                  
                          // Get and display the plugin file name:
                          const QStringList pathSplited = loader.fileName().split("/");
                          const QString fileName = pathSplited.last();
                          sendStatusMsg(tr("Loading plugin: %1").arg(fileName));
                  
                          // Cast plugin interface:
                          Plugin_API* plugin = qobject_cast<Plugin_API*>(loader.instance());
                  
                          // Error chekcing: nullptr
                          if (!plugin) {
                              sendErrorMsg(tr("Wrong Plugin API! Could not cast: %1").arg(loader.fileName()));
                              continue;
                          }
                  
                          // ===== CONNECT ALL SIGNALS /  SLOTS ===== //
                          bool conn1 = connect(plugin, &Plugin_API::sendMsg, this, &App::receivedMsg);
                          bool conn2 = connect(plugin, &Plugin_API::savePluginSettings, this, &App::receivedPluginSettings);
                  
                          bool allConnections = conn1 & conn2;
                  
                          if (!allConnections) {
                              sendErrorMsg(tr("Unable to connect: %1").arg(plugin->getName()));
                              continue;
                          }
                  
                          pluginInstance = plugin; // TRY TO USE THE POINTER
                  
                          // Store the plugin in a map:
                          _pluginsMapMap[plugin->getType()][plugin->getName()] = plugin;
                      }
                  }
                  

                  Could you please help me a little bit more?
                  How can I fix it?

                  jsulmJ JonBJ 2 Replies Last reply 5 Aug 2020, 04:40
                  0
                  • F fem_dev
                    4 Aug 2020, 21:33

                    @JonB Almost there...

                    My shared library (plugin) have a Interface Class called Plugin_API as you can see below:

                    class PLUGIN_EXPORT Plugin : public Plugin_API
                    {
                        Q_OBJECT
                        Q_PLUGIN_METADATA(IID "com.rotortest.plugin")
                        Q_INTERFACES(Plugin_API)
                    ...
                    }
                    

                    So, inside my main application I have the same Plugin_API Interface...not the Plugin class.
                    I think that the extern variable declaration must be PluginAPI type in both Qt projects (plugin and main application), right?

                    #include <iostream>
                    #include "plugin.h"
                    #include "dialog.h"
                    
                    extern Plugin_API *pluginInstance; // Changed from 'Plugin' to 'Plugin_API'
                    
                    Plugin::Plugin(QObject* parent)
                    {
                    }
                    
                    void Plugin::receivedMsg(int msgType, char* msg)
                    {
                    }
                    
                    void fortranMsg(int msgType, char* msg)
                    {
                        std::cout << msgType << " | " << msg << std::endl;
                    
                        if (pluginInstance)
                             pluginInstance->receivedMsg(msgType, msg);
                    }
                    

                    In my main application project, I opened the main GUI window Widget (called: App.cpp) and tried to add this line below:

                    #include "app.h"
                    #include "ui_app.h"
                    
                    Plugin_API *pluginInstance = nullptr;
                    
                    App::App(QWidget *parent)
                        : QMainWindow(parent)
                        , ui(new Ui::App)
                    {
                        ui->setupUi(this);
                    ...
                    }
                    

                    But I got the same run time error:

                    libLobular-Bearing.so: undefined symbol: pluginInstance
                    

                    I tried to change the pointer value inside the App:loadPlugins() method (as you can see below) but without success too.

                    void App::loadPlugins(const QStringList pluginsList)
                    {
                        foreach(QString file, pluginsList) {
                    
                            QPluginLoader loader(file);
                    
                            // Error checking:
                            if (!loader.load()) {
                                sendErrorMsg(tr("%1: ").arg(loader.errorString()));
                                continue;
                            }
                    
                            // Get and display the plugin file name:
                            const QStringList pathSplited = loader.fileName().split("/");
                            const QString fileName = pathSplited.last();
                            sendStatusMsg(tr("Loading plugin: %1").arg(fileName));
                    
                            // Cast plugin interface:
                            Plugin_API* plugin = qobject_cast<Plugin_API*>(loader.instance());
                    
                            // Error chekcing: nullptr
                            if (!plugin) {
                                sendErrorMsg(tr("Wrong Plugin API! Could not cast: %1").arg(loader.fileName()));
                                continue;
                            }
                    
                            // ===== CONNECT ALL SIGNALS /  SLOTS ===== //
                            bool conn1 = connect(plugin, &Plugin_API::sendMsg, this, &App::receivedMsg);
                            bool conn2 = connect(plugin, &Plugin_API::savePluginSettings, this, &App::receivedPluginSettings);
                    
                            bool allConnections = conn1 & conn2;
                    
                            if (!allConnections) {
                                sendErrorMsg(tr("Unable to connect: %1").arg(plugin->getName()));
                                continue;
                            }
                    
                            pluginInstance = plugin; // TRY TO USE THE POINTER
                    
                            // Store the plugin in a map:
                            _pluginsMapMap[plugin->getType()][plugin->getName()] = plugin;
                        }
                    }
                    

                    Could you please help me a little bit more?
                    How can I fix it?

                    jsulmJ Offline
                    jsulmJ Offline
                    jsulm
                    Lifetime Qt Champion
                    wrote on 5 Aug 2020, 04:40 last edited by
                    #8

                    @fem_dev said in connect: External "C" function:

                    In my main application project, I opened the main GUI window Widget (called: App.cpp) and tried to add this line below:

                    This does not make sense as pluginInstance is declared in the plug-in NOT in the application! You do not need that in main application at all - simply include the header file which contains extern Plugin_API *pluginInstance; - this is what I actually suggested before.
                    To make it short:

                    • Add extern Plugin_API *pluginInstance; to the header file inside plug-in NOT cpp file
                    • Add Plugin_API *pluginInstance = nullptr; to the corresponding cpp file inside plug-in
                    • Do NOT add Plugin_API *pluginInstance = nullptr; in main application
                    • Read about "extern", for example https://riptutorial.com/cplusplus/example/28730/extern

                    But, I'm wondering why you don't simply add pluginInstance as static member to Plugin_API...

                    https://forum.qt.io/topic/113070/qt-code-of-conduct

                    F 1 Reply Last reply 13 Aug 2020, 15:11
                    3
                    • F fem_dev
                      4 Aug 2020, 21:33

                      @JonB Almost there...

                      My shared library (plugin) have a Interface Class called Plugin_API as you can see below:

                      class PLUGIN_EXPORT Plugin : public Plugin_API
                      {
                          Q_OBJECT
                          Q_PLUGIN_METADATA(IID "com.rotortest.plugin")
                          Q_INTERFACES(Plugin_API)
                      ...
                      }
                      

                      So, inside my main application I have the same Plugin_API Interface...not the Plugin class.
                      I think that the extern variable declaration must be PluginAPI type in both Qt projects (plugin and main application), right?

                      #include <iostream>
                      #include "plugin.h"
                      #include "dialog.h"
                      
                      extern Plugin_API *pluginInstance; // Changed from 'Plugin' to 'Plugin_API'
                      
                      Plugin::Plugin(QObject* parent)
                      {
                      }
                      
                      void Plugin::receivedMsg(int msgType, char* msg)
                      {
                      }
                      
                      void fortranMsg(int msgType, char* msg)
                      {
                          std::cout << msgType << " | " << msg << std::endl;
                      
                          if (pluginInstance)
                               pluginInstance->receivedMsg(msgType, msg);
                      }
                      

                      In my main application project, I opened the main GUI window Widget (called: App.cpp) and tried to add this line below:

                      #include "app.h"
                      #include "ui_app.h"
                      
                      Plugin_API *pluginInstance = nullptr;
                      
                      App::App(QWidget *parent)
                          : QMainWindow(parent)
                          , ui(new Ui::App)
                      {
                          ui->setupUi(this);
                      ...
                      }
                      

                      But I got the same run time error:

                      libLobular-Bearing.so: undefined symbol: pluginInstance
                      

                      I tried to change the pointer value inside the App:loadPlugins() method (as you can see below) but without success too.

                      void App::loadPlugins(const QStringList pluginsList)
                      {
                          foreach(QString file, pluginsList) {
                      
                              QPluginLoader loader(file);
                      
                              // Error checking:
                              if (!loader.load()) {
                                  sendErrorMsg(tr("%1: ").arg(loader.errorString()));
                                  continue;
                              }
                      
                              // Get and display the plugin file name:
                              const QStringList pathSplited = loader.fileName().split("/");
                              const QString fileName = pathSplited.last();
                              sendStatusMsg(tr("Loading plugin: %1").arg(fileName));
                      
                              // Cast plugin interface:
                              Plugin_API* plugin = qobject_cast<Plugin_API*>(loader.instance());
                      
                              // Error chekcing: nullptr
                              if (!plugin) {
                                  sendErrorMsg(tr("Wrong Plugin API! Could not cast: %1").arg(loader.fileName()));
                                  continue;
                              }
                      
                              // ===== CONNECT ALL SIGNALS /  SLOTS ===== //
                              bool conn1 = connect(plugin, &Plugin_API::sendMsg, this, &App::receivedMsg);
                              bool conn2 = connect(plugin, &Plugin_API::savePluginSettings, this, &App::receivedPluginSettings);
                      
                              bool allConnections = conn1 & conn2;
                      
                              if (!allConnections) {
                                  sendErrorMsg(tr("Unable to connect: %1").arg(plugin->getName()));
                                  continue;
                              }
                      
                              pluginInstance = plugin; // TRY TO USE THE POINTER
                      
                              // Store the plugin in a map:
                              _pluginsMapMap[plugin->getType()][plugin->getName()] = plugin;
                          }
                      }
                      

                      Could you please help me a little bit more?
                      How can I fix it?

                      JonBJ Online
                      JonBJ Online
                      JonB
                      wrote on 5 Aug 2020, 07:36 last edited by
                      #9

                      @fem_dev
                      Briefly, I had slightly misunderstood, and taken your word that pluginInstance was to be defined in your main program. From @jsulm I now understand it is to work the other way round: you will define it in your shared library, and export it (extern) to be accessible from your main. The explanation about extern Plugin_API *pluginInstance declaration can appear many times (e.g. in a .h file) while the Plugin_API *pluginInstance definition must appear just once in a .cpp file remains the same.

                      You should follow exactly what @jsulm has instructed. If as he says you do not need to access pluginInstance outside of the shared library at all, you may be able to just define it as static there.

                      1 Reply Last reply
                      1
                      • F fem_dev
                        4 Aug 2020, 01:16

                        Thank you @JKSH for your quick response...

                        @JKSH said in connect: External "C" function:

                        There are many ways you could implement the exporting function.

                        I think that I need some help to understand in which scope should I write this lines...

                        The problem is: Only inside the main application I can write something like this:

                        Plugin *pluginInstance = nullptr; // This pointer can be updated when you construct your plugin object
                        

                        Because each plugin is loaded by the main application using QPluginLoader.
                        So, I think that I can't use this line above inside the Plugin class. Am I right?

                        Here is my plugin.h header file:

                        #include "dialog.h"
                        #include "plugin_global.h"
                        #include "plugin_qt_api.h"
                        
                        // Fortran subroutines
                        extern "C" {
                            void callFortran(...input arguments ....);
                            void fortranMsg(int msgType, char* msg);
                        }
                        
                        class PLUGIN_EXPORT Plugin : public Plugin_API
                        {
                            Q_OBJECT
                            Q_PLUGIN_METADATA(IID "com.rotortest.plugin")
                            Q_INTERFACES(Plugin_API)
                        
                        private:
                            Dialog _ui;
                        
                        public:
                        
                            explicit Plugin(QObject* parent = nullptr);
                            ~Plugin();
                        
                            //... All Methods override
                        
                            void receiveMsg(int msgType, char* msg);
                        };
                        

                        Here is my plugin.cpp implementation:

                        #include <iostream>
                        #include "plugin.h"
                        #include "dialog.h"
                        
                        Plugin::Plugin(QObject* parent)
                        {
                        }
                        
                        Plugin::~Plugin()
                        {
                        }
                        
                        void Plugin::receivedMsg(int msgType, char* msg)
                        {
                        
                        }
                        
                        void fortranMsg(int msgType, char* msg)
                        {
                            std::cout << msgType << " | " << msg << std::endl;
                        
                            // SEND DATA TO A PLUGIN METHOD
                            // HOW?
                        }
                        

                        Could you help me pass this data from the fortranMsg () function to the Plugin :: receivedMsg () method?

                        A first thought that comes to mind is that I should try to make this connection entirely within the shared library (plugin) project, without resorting to the main application project.
                        Or is there a better way to "connect" via the main application?

                        J Offline
                        J Offline
                        JKSH
                        Moderators
                        wrote on 6 Aug 2020, 00:34 last edited by
                        #10

                        @fem_dev said in connect: External "C" function:

                        Because each plugin is loaded by the main application using QPluginLoader.
                        So, I think that I can't use this line above inside the Plugin class. Am I right?

                        You are right, the example code that I wrote must be placed in your main application, not your plugin.

                        Note: That example expects a single plugin instance. If you want to load multiple plugins at the same time, then you'll need a vector of pointers, not just a single pointer.

                        A first thought that comes to mind is that I should try to make this connection entirely within the shared library (plugin) project, without resorting to the main application project.

                        I don't think that's a good design. A plugin should not be aware of the main application, so a plugin shouldn't be expected to know that fortranMsg() exists.

                        The main application should load the plugin and make all necessary "connections" to the plugin.

                        Or is there a better way to "connect" via the main application?

                        Let's step back a bit. Ignore the Fortran code for now.

                        How do you currently pass any data from your main application into your plugin objects?

                        Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                        1 Reply Last reply
                        3
                        • jsulmJ jsulm
                          5 Aug 2020, 04:40

                          @fem_dev said in connect: External "C" function:

                          In my main application project, I opened the main GUI window Widget (called: App.cpp) and tried to add this line below:

                          This does not make sense as pluginInstance is declared in the plug-in NOT in the application! You do not need that in main application at all - simply include the header file which contains extern Plugin_API *pluginInstance; - this is what I actually suggested before.
                          To make it short:

                          • Add extern Plugin_API *pluginInstance; to the header file inside plug-in NOT cpp file
                          • Add Plugin_API *pluginInstance = nullptr; to the corresponding cpp file inside plug-in
                          • Do NOT add Plugin_API *pluginInstance = nullptr; in main application
                          • Read about "extern", for example https://riptutorial.com/cplusplus/example/28730/extern

                          But, I'm wondering why you don't simply add pluginInstance as static member to Plugin_API...

                          F Offline
                          F Offline
                          fem_dev
                          wrote on 13 Aug 2020, 15:11 last edited by fem_dev
                          #11

                          @jsulm thank you...I'm almost there...
                          Here are my modifications:

                          Here is my plugin.h header file:

                          #include "dialog.h"
                          #include "plugin_global.h"
                          #include "plugin_qt_api.h"
                          
                          extern Plugin_API *pluginInstance; // FIRST MODIFICATION
                          
                          // Fortran interface
                          extern "C" {
                              void fortranMsg(int msgType, char* msg);
                          }
                          
                          class PLUGIN_EXPORT Plugin : public Plugin_API
                          {
                              Q_OBJECT
                              Q_PLUGIN_METADATA(IID "com.rotortest.plugin")
                              Q_INTERFACES(Plugin_API)
                          
                          private:
                              Dialog _ui;
                          
                          public:
                          
                              explicit Plugin(QObject* parent = nullptr);
                              ~Plugin();
                          
                              ...
                          }
                          

                          Here is my plugin.cpp implementation file:

                          #include "plugin.h"
                          #include <iostream>
                          
                          #include "dialog.h"
                          
                          Plugin_API* pluginInstance = nullptr; // SECOND MODIFICATION
                          
                          Plugin::Plugin(QObject* parent)
                          {
                              Q_UNUSED(parent)
                          }
                          
                          // Other Plugin method implementations...
                          

                          And inside the plugin.cpp I have:

                          void fortranMsg(int msgType, char* msg)
                          {
                              std::cout << msgType << " | " << msg << std::endl; // PRINT THE MSG IN THE Qt CONSOLE OK
                          
                              if (pluginInstance) {
                                  pluginInstance->sendStatusMsg(QString(msg));
                              } else {
                                  std::cout << "pluginInstance is NULL" << std::endl; // ALWAYS NULLPTR
                              }
                          }
                          

                          I do NOT declared `pluginInstance` in my `main application` // LAST MODIFICATION
                          

                          I got a clean build. No errors, no warnings! All good!
                          And I don't got any run-time erros, BUT I got always the same console message:

                          pluginInstance is NULL
                          

                          After that, I tried too:

                          Plugin_API* pluginInstance = nullptr; // SECOND MODIFICATION
                          
                          Plugin::Plugin(QObject* parent)
                          {
                              Q_UNUSED(parent)
                              
                              pluginInstance = new Plugin; // CREATE A VALID INSTANCE
                          }
                          

                          In this case, the pluginInstance is NULL console message disapears (the pointer is valid), BUT it is not calling correctly the Plugin::sendStatusMsg() method as I want.
                          So, I don't know why, I don't get the sent plugin message in my main application.

                          @JKSH here is how I communicate my own Plugin with my main application:
                          First, the plugin_qt_api.h:

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

                          Second, the plugin.h:

                          #include "plugin_global.h"
                          #include "plugin_qt_api.h"
                          
                          extern Plugin_API *pluginInstance;
                          
                          // Fortran subroutines
                          extern "C" {
                              void fortranMsg(int msgType, char* msg);
                          }
                          
                          class PLUGIN_EXPORT Plugin : public Plugin_API
                          {
                              Q_OBJECT
                              Q_PLUGIN_METADATA(IID "com.rotortest.plugin")
                              Q_INTERFACES(Plugin_API)
                          
                          public:
                          
                              explicit Plugin(QObject* parent = nullptr);
                          
                              ~Plugin();
                          
                              ...
                              void sendStatusMsg(const QString &msg) override;
                          };
                          

                          Finally, the Plugin::sendStatusMsg() method implementation inside the plugin.cpp file:

                          void Plugin::sendStatusMsg(const QString& msg) {
                              emit sendMsg("My Plugin", MSG_TYPE::STATUS_MSG, msg);
                          }
                          

                          This plugin method works good if I call it from a method inside the Plugin class. No problems here!
                          My problem is ONLY when I have to call this method from the fortranMsg() function. Because it is a function and NOT a Plugin method.

                          So, when my Fortran send a message to the C++ side, I got the message correctly in the fortranMsg() function (I can see it on Qt console), but I don't know how to pass this received message to the Plugin::sendStatusMsg() method.

                          I want to do that to enable my plugins always use the same plugin method to send messages from the plugin side to my main application.

                          As you can see above, inside my main application, I have a method called App::loadPlugin().
                          Inside of it, I have:

                          @fem_dev said in connect: External "C" function:

                          bool conn1 = connect(plugin, &Plugin_API::sendMsg, this, &App::receivedMsg);

                          Could you help me?

                          F 1 Reply Last reply 15 Aug 2020, 22:06
                          0
                          • F fem_dev
                            13 Aug 2020, 15:11

                            @jsulm thank you...I'm almost there...
                            Here are my modifications:

                            Here is my plugin.h header file:

                            #include "dialog.h"
                            #include "plugin_global.h"
                            #include "plugin_qt_api.h"
                            
                            extern Plugin_API *pluginInstance; // FIRST MODIFICATION
                            
                            // Fortran interface
                            extern "C" {
                                void fortranMsg(int msgType, char* msg);
                            }
                            
                            class PLUGIN_EXPORT Plugin : public Plugin_API
                            {
                                Q_OBJECT
                                Q_PLUGIN_METADATA(IID "com.rotortest.plugin")
                                Q_INTERFACES(Plugin_API)
                            
                            private:
                                Dialog _ui;
                            
                            public:
                            
                                explicit Plugin(QObject* parent = nullptr);
                                ~Plugin();
                            
                                ...
                            }
                            

                            Here is my plugin.cpp implementation file:

                            #include "plugin.h"
                            #include <iostream>
                            
                            #include "dialog.h"
                            
                            Plugin_API* pluginInstance = nullptr; // SECOND MODIFICATION
                            
                            Plugin::Plugin(QObject* parent)
                            {
                                Q_UNUSED(parent)
                            }
                            
                            // Other Plugin method implementations...
                            

                            And inside the plugin.cpp I have:

                            void fortranMsg(int msgType, char* msg)
                            {
                                std::cout << msgType << " | " << msg << std::endl; // PRINT THE MSG IN THE Qt CONSOLE OK
                            
                                if (pluginInstance) {
                                    pluginInstance->sendStatusMsg(QString(msg));
                                } else {
                                    std::cout << "pluginInstance is NULL" << std::endl; // ALWAYS NULLPTR
                                }
                            }
                            

                            I do NOT declared `pluginInstance` in my `main application` // LAST MODIFICATION
                            

                            I got a clean build. No errors, no warnings! All good!
                            And I don't got any run-time erros, BUT I got always the same console message:

                            pluginInstance is NULL
                            

                            After that, I tried too:

                            Plugin_API* pluginInstance = nullptr; // SECOND MODIFICATION
                            
                            Plugin::Plugin(QObject* parent)
                            {
                                Q_UNUSED(parent)
                                
                                pluginInstance = new Plugin; // CREATE A VALID INSTANCE
                            }
                            

                            In this case, the pluginInstance is NULL console message disapears (the pointer is valid), BUT it is not calling correctly the Plugin::sendStatusMsg() method as I want.
                            So, I don't know why, I don't get the sent plugin message in my main application.

                            @JKSH here is how I communicate my own Plugin with my main application:
                            First, the plugin_qt_api.h:

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

                            Second, the plugin.h:

                            #include "plugin_global.h"
                            #include "plugin_qt_api.h"
                            
                            extern Plugin_API *pluginInstance;
                            
                            // Fortran subroutines
                            extern "C" {
                                void fortranMsg(int msgType, char* msg);
                            }
                            
                            class PLUGIN_EXPORT Plugin : public Plugin_API
                            {
                                Q_OBJECT
                                Q_PLUGIN_METADATA(IID "com.rotortest.plugin")
                                Q_INTERFACES(Plugin_API)
                            
                            public:
                            
                                explicit Plugin(QObject* parent = nullptr);
                            
                                ~Plugin();
                            
                                ...
                                void sendStatusMsg(const QString &msg) override;
                            };
                            

                            Finally, the Plugin::sendStatusMsg() method implementation inside the plugin.cpp file:

                            void Plugin::sendStatusMsg(const QString& msg) {
                                emit sendMsg("My Plugin", MSG_TYPE::STATUS_MSG, msg);
                            }
                            

                            This plugin method works good if I call it from a method inside the Plugin class. No problems here!
                            My problem is ONLY when I have to call this method from the fortranMsg() function. Because it is a function and NOT a Plugin method.

                            So, when my Fortran send a message to the C++ side, I got the message correctly in the fortranMsg() function (I can see it on Qt console), but I don't know how to pass this received message to the Plugin::sendStatusMsg() method.

                            I want to do that to enable my plugins always use the same plugin method to send messages from the plugin side to my main application.

                            As you can see above, inside my main application, I have a method called App::loadPlugin().
                            Inside of it, I have:

                            @fem_dev said in connect: External "C" function:

                            bool conn1 = connect(plugin, &Plugin_API::sendMsg, this, &App::receivedMsg);

                            Could you help me?

                            F Offline
                            F Offline
                            fem_dev
                            wrote on 15 Aug 2020, 22:06 last edited by fem_dev
                            #12

                            @fem_dev Thank you @JKSH @jsulm and @JonB for all help in this topic! I really need to say "thank you"! You all are great!

                            With your help I finally solve this problem.

                            Here is my plugin.h header file:

                            extern Plugin_API *pluginInstance; // <-- 1. CREATE A GLOBAL INTERFACE CLASS POINTER
                            
                            extern "C" {
                                void fortranMsg(int msgType, char* msg);
                            }
                            
                            class PLUGIN_EXPORT Plugin : public Plugin_API
                            {
                                Q_OBJECT
                                Q_PLUGIN_METADATA(IID "com.rotortest.plugin")
                                Q_INTERFACES(Plugin_API)
                            
                            public: 
                                ...
                                void sendStatusMsg(const QString &msg) override;
                            }
                            

                            Here is my plugin.cpp implementation file:

                            Plugin_API* pluginInstance = nullptr; // <-- 2. Init the global pointer to nullptr
                            
                            Plugin::Plugin(QObject* parent)
                            {
                                pluginInstance = this; // <-- 3. Point to the current object
                            }
                            

                            Now, I can use the global variable pluginInstance inside a pure function too.
                            With this pointer, I can call any Plugin method from any pure function. Like:

                            void fortranMsg(int msgType, char* msg)
                            {
                                pluginInstance->sendStatusMsg(QString(msg));    
                            }
                            

                            That's it!

                            Thank you all again!

                            1 Reply Last reply
                            1
                            • J Offline
                              J Offline
                              JKSH
                              Moderators
                              wrote on 16 Aug 2020, 05:40 last edited by
                              #13

                              @fem_dev, you're welcome. Happy coding! :)

                              I'm curious though: It looks like your app only loads 1 instance of the plugin, is that right? If that's the case, what is the purpose of having a Plugin API?

                              Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                              F 1 Reply Last reply 18 Aug 2020, 13:18
                              0
                              • J JKSH
                                16 Aug 2020, 05:40

                                @fem_dev, you're welcome. Happy coding! :)

                                I'm curious though: It looks like your app only loads 1 instance of the plugin, is that right? If that's the case, what is the purpose of having a Plugin API?

                                F Offline
                                F Offline
                                fem_dev
                                wrote on 18 Aug 2020, 13:18 last edited by
                                #14

                                @JKSH said in connect: External "C" function:

                                only loads 1 instance of the plugin

                                No @JKSH ...my main application should load many plugins...

                                What part of my code above made you think that my main application only loads a single plugin?

                                Did I write something wrong?

                                J 1 Reply Last reply 18 Aug 2020, 13:54
                                0
                                • F fem_dev
                                  18 Aug 2020, 13:18

                                  @JKSH said in connect: External "C" function:

                                  only loads 1 instance of the plugin

                                  No @JKSH ...my main application should load many plugins...

                                  What part of my code above made you think that my main application only loads a single plugin?

                                  Did I write something wrong?

                                  J Offline
                                  J Offline
                                  JKSH
                                  Moderators
                                  wrote on 18 Aug 2020, 13:54 last edited by JKSH
                                  #15

                                  @fem_dev said in connect: External "C" function:

                                  No @JKSH ...my main application should load many plugins...

                                  What part of my code above made you think that my main application only loads a single plugin?

                                  You only have 1 pluginInstance pointer. That means fortranMsg() can only send the message to 1 plugin.

                                  Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                                  F 1 Reply Last reply 19 Aug 2020, 00:56
                                  0
                                  • J JKSH
                                    18 Aug 2020, 13:54

                                    @fem_dev said in connect: External "C" function:

                                    No @JKSH ...my main application should load many plugins...

                                    What part of my code above made you think that my main application only loads a single plugin?

                                    You only have 1 pluginInstance pointer. That means fortranMsg() can only send the message to 1 plugin.

                                    F Offline
                                    F Offline
                                    fem_dev
                                    wrote on 19 Aug 2020, 00:56 last edited by
                                    #16

                                    @JKSH said in connect: External "C" function:

                                    You only have 1 pluginInstance pointer.

                                    Yes! That's right!

                                    Inside my plugin, I have only one pluginInstance pointer.

                                    Each plugin is a isolated Qt shared library project. So inside of each plugin I must have only your own pluginInstance pointer.

                                    My main application will load all compiled plugins after that.

                                    1 Reply Last reply
                                    0

                                    • Login

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