信号/槽原理分析_如何查看与分析QT的源码实现
(课堂案例分享, 首次发帖, 若有错误与不足之处, 希望指正)
步骤
创建demo
配置环境, 加载静态库
修改demo, 分析moc文件
定位关键点, 分析关键函数
使用工具
Visual Studio 2015
QT 5.11.2
Source Insight
1. 创建demo
#include <QObject>
class CStudent : public QObject
{
Q_OBJECT
public:
CStudent(QObject *parent);
~CStudent();
void SetAge(int nAge) {
emit age(3, nAge);
}
signals:
void age(int n, double nAge);
public slots:
void OnAgedChange(int n, double nAge) {
m_nAge = nAge;
}
private:
int m_nAge;
};
2.1 Visual Studio 环境配置
QT版本配置 (Change QT version)
安装QT源码, 并在源目录中添加QT源码地址
在 工具 - 选项 中添加 pdb 文件目录
测试: F12点进代码中的宏 signals中, 可以得到以下界面, 则表示配置成功!
2.2 Source Insight 环境配置
Source Insight中创建新项目, 将项目名称改为QtSource
找到QT源码安装目录, 回车, 再加载安装目录中的所有文件
包含顶层文件和内部文件, 两个都选中
关闭窗口, 窗口右侧有文件, 则创建项目成功
3 moc文件分析
qt_meta_stringdata_CStudent_t : 存储类的字符串相关信息
qt_meta_data_CStudent : 存储类中函数相关的信息
函数名在 qt_meta_stringdata_CStudent_t 中的存储编号
参数个数
该函数的具体声明在 qt_meta_data_CStudent 中的偏移量
staticMetaObject : 类信息的总和
qt_metacast : 返回类名称
qt_metacall : 函数调用
void **_a : 数组指针, 每个指针指向一个函数的地址
_c : 函数的实现类型
_id : 函数id, 判断是否实现 & 以何种方式实现该函数
void CStudent::age(int _t1, double _t2) : 信号的实现
metaObject : 判断静态/动态调用
4.1 定位关键点 QObject
Q_OBJECT 宏
4.2 定位关键点 connection
如何定位?
方法一 : 在VS中进入单步调试模式, 在connect函数上下断点, F11跟进至connect函数中查看函数实现源码
方法二 : 打开Source Insight, 打开QtSource工程, 在搜索栏中查询QObject.conncet, 得到函数实现的源码
connect函数 : 判断并转化输入的数据, 将数据封装成QT库函数中可以接收的参数, 并调用Connection函数关联信号与槽
实现流程:
Connection函数 : 将信号槽的关联信息以哈希表的形式存储
实现流程
4.3 定位关键点 active
如何定位?
在槽的实现位置下断点, F5运行至断点后通过下图左下角的栈回溯找到active的实现函数
函数关键点分析
查找关联链表位置
调用关联链表中的槽函数
本文由看雪论坛 埃斯艾克斯 原创
网友评论