如何枚举Qt中所有的QObject类?

发布于 2024-12-08 15:44:55 字数 163 浏览 1 评论 0 原文

有没有办法枚举应用程序或 DLL 中声明的所有 QObject 类?我正在尝试创建一个加载 DLL 并列出 DLL 内的所有 QObject 类的应用程序。

更新:实际上我正在尝试创建一个单元测试 GUI。它将加载 DLL,实例化内部的 QObject,并针对它们调用 QTest::qExec。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

染柒℉ 2024-12-15 15:44:55

如果程序代码没有被剥离,您可以通过阅读二进制文件进行一些内省:
objdump -demangle=C++ -t SomeQtLibrary.so |grep qt_static_metacall 它大致显示了 QObject 派生类。我认为他们都实现了这个符号。当然,由于您使用的是 Windows,因此您必须使用 Windows 工具,例如 nm(如果我错了,请纠正我)。当然,在代码中处理符号也是可能的,但这是一个单独的主题。

例如,我提到的命令会返回以下内容:

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**)

如果您对运行时自省感兴趣,则必须使用 QMetaObject 类。

对于注册为 QMetaType 的对象(仅限这些!),您可以执行一些操作额外的魔法让它们栩栩如生。不是很容易,也不是开箱即用的——但对于这样一种静态语言来说,它仍然是地狱般的。以下是 Qt 文档的片段(将 if(id == 0) 更改为 if(id))。

 int id = QMetaType::type("MyClass");
 if (id) {
     void *myClassPtr = QMetaType::construct(id);
     ...
     QMetaType::destroy(id, myClassPtr);
     myClassPtr = 0;
 }

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;
 }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文