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

Convert Plugin interface into a Factory class



  • I have a situation wherein i have a plugin interface as shown below:

    class Device
    {
        public:
    
            /**
             * @brief Virtual destructor
             */
            virtual ~Device() = default;      
    
            /**
             * @brief Start the device
             */
            virtual void start() = 0;
    
            /**
             * @brief Stop the device
             */
            virtual void stop() = 0;        
    };
    
    #define iIterface_IID "com.company.Device/1.0"
    Q_DECLARE_INTERFACE(Device, iIterface_IID)
    

    And 2 more implementing plugins SensorA and SensorB which look almost similar:

    class SensorA : public QObject, public Device
    {
            Q_OBJECT
            Q_PLUGIN_METADATA(IID "com.company.SensorA")
            Q_INTERFACES(Device)
    
        public:
    
            /**
             * @brief Constructor
             */
            SensorA();
    
            /**
             * @brief Destructor
             */
            ~SensorA();
    
            /**
             * @brief   Establishes a connection to the sensor.
             *
             * @return  True if the connect was successfully established.
             */
            bool connect();
    
            /**
             * @brief Start the sensor
             */
            virtual void start() override;
    
            /**
             * @brief Stop the sensor
             */
            virtual void stop() override;
    };
    

    I have a pluginloader class which spits out a Device* instance using:

    Device* PluginLoader::load()
    {
         // initiate loading
        QPluginLoader* pluginLoader = new QPluginLoader(this);
        pluginLoader->setFileName("SensorA"); // omitting .dll suffix as per documentation
    
        if (!pluginLoader->load())
        {
            qWarning() << "Plugin loading failed..." << pluginLoader->errorString();
            return nullptr;
        }
    
        qInfo() << "Plugin loaded successfully!!!";
    
        // get plugin instance
        Device* device = dynamic_cast<Device*>(pluginLoader->instance()); // here is the issue. Returns the root component object of the plugin
    
        return device;
    }
    

    I would like my load() to return Device* based on classType of my choice. As i am trying to implement lazy loading of the .dlls, this is how i want it to be:

    Action1: User chooses to connect to SensorA
    Action2: Load the plugin SensorA using QPluginLoader
    Action3: load() must return something like:

    Device* device = new SensorA();
    

    Or more conventionally, i want to make my plugin class a factory for the class type i wish to use. Any workarounds or ideas?


  • Qt Champions 2019

    But your loader already returns an instance of SensorA when it loads the plugin for SensorA, or?


  • Lifetime Qt Champion

    Hi,

    The usual way is to pass the information to the factory method so it can load the appropriate class.

    You can also check the plug and paint example for another way to do that.



  • @Christian-Ehrlicher Does it? How does it know which instance to return? Maybe i misunderstood the documentation "Returns the root component object of the plugin" part.


  • Qt Champions 2019

    @MarKS said in Convert Plugin interface into a Factory class:

    How does it know which instance to return?

    It returns a Device* pointer which you can cast to your specific instance although this completely contradicts the use of an interface.



  • @Christian-Ehrlicher Alright! Then how do you suggest i should implement to get my desired instance?


  • Qt Champions 2019

    Enhance your interface, otherwise it's useless.


Log in to reply