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

How to receive signal from an object built in a dynamically loaded library



  • Hi,

    I create this Github repository to illustrate my issue.

    I have an application with some libraries that must be loaded dynamically. These libraries (called "pluginX" in my example) contain some classes based on QObject (TypeXX in my example). These classes have some functions, slots and signals.
    My application can load the plugin, call functions and slots and receive signals from the main instance of it. After my application asked the plugin to instanciate a class from the library, it can call functions and slots from this instance but not receive any signals.

    How can I do what I want ?

    Thanks.

    Francis



  • If I use the old signal connection style "SIGNAL(...)", it works fine.

    I am very disappointed to have to use this method.

    I have to be pragmatic because I don't have time to keep looking for a solution, but if someone has one for me, I'm 100% taker.

    I'll leave the topic open for a few days, maybe to have a better solution, then I'll mark it as resolved.

    Thanks.


  • Lifetime Qt Champion

    @Francis-Chapet said in How to receive signal from an object built in a dynamically loaded library:

    but not receive any signals

    So, did you connect the signals to slots? Did you make sure the signals were actually emitted?



  • @jsulm Yes, I use the same method to test signal with the plugin class and type class, I receive it from the plugin but not from the type.


  • Lifetime Qt Champion

    @Francis-Chapet Please first check wheter this type class emits the signal.
    Also, please show how you connect signals and slots.



  • @jsulm It is in the file d_plugins_loader.cpp in this Github repository, in the function "checkTypeCreation". I copy it bellow:

    
    bool DPluginsLoader::checkTypeCreation(const QString & type)
    {
    	const QVariant prm("un peu de texte");
    	bool ret = m_types.contains(type);
    
    	if (ret) {
    		pIPlugin plugin = m_types.value(type);
    		QObject * object = plugin->getInstance(type, prm, this);
    		IType * tp01 = qobject_cast<IType *>(object);
    		QVariant params = tp01->getParameters();
    		if (params == prm) {
    			qDebug() << type << "return parameters" << params;
    		} else {
    			qDebug() << type <<  "did not return good values!" << params;
    			ret = false;
    		}
    		if (ret) {
    			// Verify plugin emits its `name` with `QSignalSpy`.
    			QSignalSpy spy(tp01, & IType::sigParameters);
    			QTimer::singleShot(100, tp01, & IType::sltParameters);
    			spy.wait();
    			if (spy.count() == 1) {
    				auto prms = spy.takeFirst().at(0).toString();
    				qDebug() << type << "emitted parameters:" << prms;
    			} else {
    				qDebug() << type << "did not emit parameters!";
    				ret = false;
    			}
    		}
    	}
    	return ret;
    }
    
    

  • Lifetime Qt Champion

    @Francis-Chapet So, was "emitted parameters:" printed or not?
    You should actually check in the plug-in code whether it emits the signal or not (add a qDebug() befor emitting the signal).



  • @jsulm This is the case and this is the output displayed :

    Type "Type01" loaded !
    Type "Type02" loaded !
    Plugin "Plugin 0" loaded !
    Plugin emitted name: "Plugin 0"
    Type "Type11" loaded !
    Type "Type12" loaded !
    Plugin "Plugin 1" loaded !
    Plugin emitted name: "Plugin 1"
    Type "Type21" loaded !
    Type "Type22" loaded !
    Plugin "Plugin 2" loaded !
    Plugin emitted name: "Plugin 2"
    Type "Type31" loaded !
    Type "Type32" loaded !
    Plugin "Plugin 3" loaded !
    Plugin emitted name: "Plugin 3"
    "Type01" return parameters QVariant(QString, "un peu de texte")
    virtual void Type01::sltParameters()
    "Type01" did not emit parameters!
    "Type02" return parameters QVariant(QString, "un peu de texte")
    virtual void Type02::sltParameters()
    "Type02" did not emit parameters!
    "Type11" return parameters QVariant(QString, "un peu de texte")
    virtual void Type11::sltParameters()
    "Type11" did not emit parameters!
    "Type12" return parameters QVariant(QString, "un peu de texte")
    virtual void Type12::sltParameters()
    "Type12" did not emit parameters!
    "Type21" return parameters QVariant(QString, "un peu de texte")
    virtual void Type21::sltParameters()
    "Type21" did not emit parameters!
    "Type22" return parameters QVariant(QString, "un peu de texte")
    virtual void Type22::sltParameters()
    "Type22" did not emit parameters!
    "Type31" return parameters QVariant(QString, "un peu de texte")
    virtual void Type31::sltParameters()
    "Type31" did not emit parameters!
    "Type32" return parameters QVariant(QString, "un peu de texte")
    virtual void Type32::sltParameters()
    "Type32" did not emit parameters!
    


  • If I use the old signal connection style "SIGNAL(...)", it works fine.

    I am very disappointed to have to use this method.

    I have to be pragmatic because I don't have time to keep looking for a solution, but if someone has one for me, I'm 100% taker.

    I'll leave the topic open for a few days, maybe to have a better solution, then I'll mark it as resolved.

    Thanks.



  • What platform are you compiling this on?

    If it is Windows (with Visual Studio, MSVC, cl.exe), I always feel a suspicion around the whole idea of "dllimport/dllexport". But that isn't a specific, actionable piece of advice. That's just a stray idea that might lead to fruitful research.

    I have a Qt/QML app that is using a custom plugin. I don't directly use signals, but I use a Q_PROPERTY, which I think ends up adding at least one signal on my behalf ("behind the scenes").

    The Q_PROPERTY in a plugin DLL is working. Here is the header: https://github.com/219-design/qt-qml-project-template-with-ci/blob/a849fbba4fb/src/libstyles/resource_helper.h

    ... and here is the pro file for compiling the DLL: https://github.com/219-design/qt-qml-project-template-with-ci/blob/a849fbba4fb51c5d8618284df0c70c26f4a229a2/src/libstyles/libstyles.pro

    Other than my use of the dllexport MSVC stuff, the only other thing that I notice is that my pro file has this:

    CONFIG += plugin
    

    Whereas I do not find CONFIG += plugin in your git repository. But I do not specifically know what "magic" is achieved by CONFIG += plugin.



  • @KH-219Design Thanks a lot for your advices.

    I develop and test on Windows 10 but my application will be used on an embedded linux plateform (built with Yocto).

    I use Qt 5.13.2 framework, Qt creator as IDE and MinGW 7.3.0 64-bit compiler


Log in to reply