如何使用 .dll 注入覆盖 Qt 成员函数
Posted
技术标签:
【中文标题】如何使用 .dll 注入覆盖 Qt 成员函数【英文标题】:How to override Qt member function with .dll injection 【发布时间】:2015-11-06 14:57:43 【问题描述】:我正在尝试提供一些代码here 的Windows 版本,用于记录Qt (4.7) 事件。目标应用程序是基于 Qt 的,执行注入的代码 fwiw 也是如此。 linux 版本使用库预加载来覆盖 QWidget::x11event 作为录制代码的起点。
我也尝试过这样做,将 winEvent 用作 x11event 的适当等效项。我正在使用 dll 注入,据我所知是成功的。 dll在调试器的加载模块中列出并且加载例程都成功。
但是我从来没有看到我的 winEvent 被调用。我尝试用相同的结果覆盖其他函数。
我是 dll 创建的新手,更不用说注入了,所以可能在某处遗漏了一个重要步骤,但是当我构建包含我的 winEvent 实现的 .dll 时,编译器警告引起了我的怀疑;我收到“警告 C4273:'QWidget::winEvent':dll 链接不一致”。 dll虽然编译成功。目前我只是有
bool QWidget::winEvent ( MSG *message, long *result)
// my code
在我的 .dll 中的其中一个 cpp 文件中。这够了吗?
【问题讨论】:
如果你想在一个开源应用程序中重写一个函数,为什么不自己改变源代码呢?处理 DLL 注入的麻烦有什么意义? 开源代码通过使用库预加载在 linux 中记录任何 Qt 目标应用程序中的用户操作。我在 Windows 中最接近的方法是 dll 注入。 【参考方案1】:Qt 如何使其类 DLL 导出?
class Q_WIDGETS_EXPORT QWidget : public QObject, public QPaintDevice
或者更早的 Qt 暴露了相同的类:
class Q_GUI_EXPORT QWidget : public QObject, public QPaintDevice
什么是 Q_WIDGETS_EXPORT?毕竟动态Qt的#ifdef/#define重定向你应该得到它的值:
__declspec(dllexport)
这是在您的普通 Qt 应用程序项目中设置的。对于包含 Qt 标头之前的那个 DLL 注入项目(我猜),您可以尝试这样做:
#define Q_WIDGETS_EXPORT __declspec(dllexport)
或
#define Q_GUI_EXPORT __declspec(dllexport)
或 弄清楚如何将 Q_GUI_EXPORT 的值设为 __declspec(dllexport)
您应该仔细检查宏 Q_WIDGETS_EXPORT 以及您尝试使用 DLL 注入的特定 Qt 版本。我偷看了 Qt 5.3.2 的源代码。
记住 DLL 导出和导入范例,对于您的应用项目,它是导入,对于 DLL 公开函数,它是导出。就像国际贸易一样。
【讨论】:
感谢您的建议,不幸的是,它似乎没有帮助。在我重新定义 QWidget::winEvent 的 .cpp 文件中,我还有其他 Qt 代码应该引入那些#defines,所以我不会太惊讶。 那么不清楚那个DLL项目到底是怎么实现的?带有 QWidget::winEvent 的文件包括什么? 在Qt 4.7中,QWidget被定义为:class Q_GUI_EXPORT QWidget : public QObject, public QPaintDevice,而Q_GUI_EXPORT被定义为#define Q_GUI_EXPORT Q_DECL_IMPORT,又是#define Q_DECL_IMPORT __declspec(dllimport)(对不起我不清楚如何在不导致发布的情况下格式化此评论!)。这似乎与您的 dllexport 不一致。有什么想法吗?我覆盖 QWidget::winEvent 的代码包括以上是关于如何使用 .dll 注入覆盖 Qt 成员函数的主要内容,如果未能解决你的问题,请参考以下文章
Qt DLL总结-VS2008+Qt 使用QPluginLoader访问DLL
MFC 应用程序中的 Qt DLL - 如何使 QDialog *真正* 模态?