Please nominate your Qt Champions for 2021!

QObject::connect with different threads: object with private constructors is lost when slot called

  • Hi,

    In the atttached small example (the actual issue I have is from a much bigger project) you can find attached:

    • The class MyClass has been set to be constructed with macros in order to get contextual PRETTY_FUNCTION this is why it has private constructors,
    • It has been registered properly, at least for what I know, including QMetaTypeFunctionHelper since it has private constructors (see MetaTypeRegistration source and header),
    • When pressing "Go" button, MyModel::Go is called, making a threaded call to MyModel::_Go() function where a MyClass object is created and then, MyClass string will contain "void MyModel::_Go()"
    • Then MyModel::MySignal is emitted with myClass object, and since it has been connected to MainWindow::MySlot, this function is triggered, but, and this is the issue of this bug, with a default constructed MyClass as parameter (you can see in logs and in text browser that "void MyModel::_Go()" is actually in object sent by signal but "<default>" is received in slot),

    I have found this seems to be both a threading and a QMetaTypeFunctionHelper issue since I've performed test in other contexts:

    • You can comment DEFINES += THREADED_GO in pro file and rebuild (it is not automatically done in Qt Creator then press right click -> "Rebuild" in the project head) to see that without threading it works fine,
    • Another test is to let THREADED_GO define but comment definition of PRIVATE_CONSTRUCTORS and see that even with public default constructors, if QMetaTypeFunctionHelper is declared it does not work,
    • And finally with THREADED_GO defined but PRIVATE_CONSTRUCTORS and PRIVATE_FUNCTION_HELPER not defined (public constructors without QMetaTypeFunctionHelper declared) it works.

    Anybody knows if am I missing something (mainly in QMetaTypeFunctionHelper) ?


    Edit: upload since not working ("not enough privilege ?), here is the file posted elsewhere: (not sure if the interface is available in English, if not click on "Valider et télécharger le fichier" to download it).

  • Lifetime Qt Champion

    Your implementation of 'Construct(void *where, const void *t)' is wrong - you ignore the 'void *t' parameter.

  • @Christian-Ehrlicher OK, thanks a lot, now I feel dump, I just copy/paste a code modifying the Create function but not the Construct, with this it actually works as expected:

    static void *Construct(void *where, const void *t)
        if (!t)
            return new (where) MyClass(CREATE_DEFAULT_MY_CLASS());
        return new (where) MyClass(*static_cast<const MyClass*>(t));

    Thanks again

Log in to reply