Hi! I have a QThread where I perform SQL queries. Now that my application has grown, I want to many it modular by creating modules that live in that thread, i.e. classes that are instantiated and perform their work in that thread.

However, I would like to do it in a way the QThread doesn't need to know of each of the classes it has. It would just get the list of class names and instantiate them without needing to know which are their constructors.

I thought of registering every module as a metatype, then passing the class name to the QThread and using QMetaType::construct() in it to be able to instantiate them. It would look like this:

Qt Code:
  1. class DbThread : public QThread
  2. {
  3. Q_OBJECT
  4.  
  5. public:
  6. DbThread(QObject *parent = 0);
  7. void constructExtensions();
  8. void queryExtensions();
  9. void registerExtension(const QString& type);
  10.  
  11. private:
  12. QStringList m_extensionNames;
  13. QList<Extension*> m_extensions;
  14. };
  15.  
  16.  
  17. void DbThread::constructExtensions()
  18. {
  19. foreach(const QString& className, m_extensionNames) {
  20. QByteArray classNameBA = className.toLocal8Bit();
  21. int id = QMetaType::type(classNameBA.constData());
  22. if(id != -1) {
  23. void *myClassPtr = QMetaType::construct(id);
  24. if(myClassPtr == 0) {
  25. qDebug() << "Failed instantiating the module:" << className;
  26. continue;
  27. }
  28. Extension *extension = (Extension*) myClassPtr;
  29. extension->setParent(this);
  30. m_extensions.append(extension);
  31. }
  32. }
  33. }
  34.  
  35.  
  36. void DbThread::queryExtensions()
  37. {
  38. foreach(Extension *ext, m_extensions)
  39. ext->doSomething();
  40. }
  41.  
  42.  
  43. void DbThread::registerExtension(const QString& type)
  44. {
  45. m_extensionNames << type;
  46. }
To copy to clipboard, switch view to plain text mode 

I use the class Extension which is in fact an interface. Other modules are subclasses of it. For example:

Qt Code:
  1. #include <QMetaType>
  2. #include <QObject>
  3. #include <QString>
  4. #include "extension.h"
  5.  
  6. class CoolExtension : public Extension
  7. {
  8. Q_OBJECT
  9.  
  10. public:
  11. CoolExtension(QObject *parent = 0);
  12. CoolExtension(const CoolExtension& other);
  13. void doSomething();
  14. };
  15.  
  16. Q_DECLARE_METATYPE(CoolExtension)
To copy to clipboard, switch view to plain text mode 

Then I would call DbThread::registerExtension("CoolExtension") so that constructExtensions() would instantiate one object of the CoolExtension class.

That is the idea. However the application segfaults after I try to use the pointer QMetaType::construct() gave me. The pointer is not null but it seems QMetaType::construct() is not doing what I expect or I can't convert it properly. What might be wrong?

Do you have a better idea on how to create modules that must be instantiated by a QThread since they live in it? Perhaps should I instantiate them somewhere else and use QThread::moveToThread()? But I don't like the idea of instantiating in one thread and moving to another one.

Thanks.