Solved 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) ?
Thanks
Edit: upload since not working ("not enough privilege ?), here is the file posted elsewhere: http://dl.free.fr/getfile.pl?file=/gHSMmrvW (not sure if the interface is available in English, if not click on "Valider et télécharger le fichier" to download it).
-
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