Question

Is there a way to enumerate all QObject classes declared in an application or DLL? I am trying to create an application that loads DLLs and lists all QObject classes inside the DLLs.

Update: Actually I am trying to create a Unit Test GUI. It will load DLLs, instantiate the QObject inside, and call QTest::qExec against them.

Was it helpful?

Solution

If the program code is not stripped you can get some instrospection by reading the binary: objdump -demangle=C++ -t SomeQtLibrary.so |grep qt_static_metacall it shows roughly the QObject derived classes. I think they all implement this symbol. Of couse since you are on Windows you would have to use Windows tools such as nm (correct me if I am wrong). Naturally processing the symbols in-code is also possible, but this is a separate topic.

The command I mentioned returns this for example:

0000000000470c00 l     F .text  0000000000000014              QxtBoundFunction::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)
00000000004392ea l     F .text  0000000000000158              MainWindow::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)
0000000000453b5c l     F .text  0000000000000091              QtLocalPeer::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)
0000000000438508 l     F .text  0000000000000014              MyApplication::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)
0000000000442cd0 l     F .text  0000000000000080              MessagePoll::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)
0000000000442ea2 l     F .text  0000000000000091              RFBClient::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)
0000000000467c3c l     F .text  000000000000436a              QxtRPCService::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)
0000000000439114 l     F .text  000000000000008f              MemoryPolling::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)

If you are interested in run-time introspection than you would have to play with the QMetaObject class on each object.

For objects that were registered as QMetaType (and only those!) you can do some additional magic to bring them to life. Not very easy, and not out of the box - but it is still hell of a lot from such a static language. Here is a snippet from Qt docs (changed if(id == 0) to if(id)).

 int id = QMetaType::type("MyClass");
 if (id) {
     void *myClassPtr = QMetaType::construct(id);
     ...
     QMetaType::destroy(id, myClassPtr);
     myClassPtr = 0;
 }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top