Qt Moc 文件解析
Qt Moc文件详解
- Moc文件内容
- 类原始代码
- 生成后Moc文件解析
Moc文件内容
Moc 文件是Qt moc工具生成的实现文件,用于实现Qt的元对象系统
类原始代码
class ParseQObject : public QObject
{Q_OBJECTQ_PROPERTY(int prop1 READ prop1 WRITE setProp1)// 属性1
public:explicit ParseQObject(QObject *parent = nullptr);//can create instance constructor 1Q_INVOKABLE ParseQObject(int constructIntParam, QObject *constructParentParam = nullptr);
signals:void sig1();//信号1void sig2(int sigParam2int);//信号2void sig3(char sigParam3char, int sigParam3int);//信号3
public slots:void slot1();//槽1void slot2(int slotParam2);//槽2void slot3(char slotParam3char, int slotPram3int);//槽3public:Q_INVOKABLE void InvokeFunc();//invoke function 1Q_INVOKABLE int InvokeFuncWithReturn();//invoke func 2int prop1();void setProp1(int v);private:int prop_1;
};
生成后Moc文件解析
QT_BEGIN_MOC_NAMESPACE
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
struct qt_meta_stringdata_ParseQObject_t {QByteArrayData data[19];char stringdata0[203];
};
//QT_MOC_LITERAL宏展开
/*//前置宏定义
struct Q_CORE_EXPORT QArrayData
{QtPrivate::RefCount ref;int size;uint alloc : 31;uint capacityReserved : 1;qptrdiff offset; // in bytes from beginning of headervoid *data(){Q_ASSERT(size == 0|| offset < 0 || size_t(offset) >= sizeof(QArrayData));return reinterpret_cast<char *>(this) + offset;}
}
typedef QArrayData QByteArrayData;//qbytearry
#define Q_BASIC_ATOMIC_INITIALIZER(a) { (a) }#define Q_REFCOUNT_INITIALIZE_STATIC { Q_BASIC_ATOMIC_INITIALIZER(-1) }#define Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(size, offset) \{ Q_REFCOUNT_INITIALIZE_STATIC, size, 0, 0, offset } #define Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(size, offset) \Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(size, offset)/
#define QT_MOC_LITERAL(idx, ofs, len) \Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \qptrdiff(offsetof(qt_meta_stringdata_ParseQObject_t, stringdata0) + ofs \- idx * sizeof(QByteArrayData)) \)/********offsetof(qt_meta_stringdata_ParseQObject_t, stringdata0) stringdata0 在 qt_meta_stringdata_ParseQObject_t中的偏移宏拆开后,对应一个QByteArrayData{ -1, len, //字符串长度0, 0, qptrdiff(offsetof(qt_meta_stringdata_ParseQObject_t, stringdata0) - idx * sizeof(QByteArrayData) + ofs ) //是对应stringdata0中此字段字符串中的首地址}//qt_meta_stringdata_ParseQObject_t, stringdata0) 字符串在结构体的偏移 256//qptrdiff(offsetof(qt_meta_stringdata_ParseQObject_t, stringdata0) - idx * sizeof(QByteArrayData) QByteArrayData data[16] ,数组元素[i]在结构体的偏移// 上式 + ofs(字符串的偏移) 即为求字符串的地址sizeof(QByteArrayData) = 16;假设stringdata0在qt_meta_stringdata_ParseQObject_t的偏移为19*16sig_2的索引为2则QBytearrayData data[2]= {-1,len,0,0,offset=19*16 - 2 * 16 + 18;为什么不是19*16 + 18呢?即为什么不是直接字符串首地址加偏移呢?答:因为QByteArrayData 求数据函数data定义为 void *data(){Q_ASSERT(size == 0|| offset < 0 || size_t(offset) >= sizeof(QArrayData));return reinterpret_cast<char *>(this) + offset; //此处的this 为data[2]的地址,data[2]的地址为 2 * sizeof(QByteArrayData),如果不减去data[2]的偏移,则相当于从data[2]开始+偏移+stringdata0的偏移,取到的是错误的地址//所以减去data[2]相对于qt_meta_stringdata_ParseQObject_t的偏移,将偏移定位到qt_meta_stringdata_ParseQObject_t的首地址0处}}data[0]的地址: ParseQObject = 19*16 - 0 * 16 + 0 data[1]的地址: sig1 = 19*16 - 1 * 16 + 13 sig2sigParam2intsig3sigParam3charsigParam3intslot1slot2slotParam2slot3slotParam3charslotPram3intInvokeFuncdata[15]的地址: InvokeFuncWithReturn = 19*16 - 15* 16 + 137 ...data[18]的地址:prop1 = 19*16 - 18 * 16 + 197
********/
*/
#define QT_MOC_LITERAL(idx, ofs, len) \Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \qptrdiff(offsetof(qt_meta_stringdata_ParseQObject_t, stringdata0) + ofs \- idx * sizeof(QByteArrayData)) \)
static const qt_meta_stringdata_ParseQObject_t qt_meta_stringdata_ParseQObject = {{//(0:索引, 0:对应字符串的偏移, 12:字符串的长度) 即"ParseQObject"
QT_MOC_LITERAL(0, 0, 12), // "ParseQObject"
QT_MOC_LITERAL(1, 13, 4), // "sig1"
QT_MOC_LITERAL(2, 18, 0), // "" //参数为空
QT_MOC_LITERAL(3, 19, 4), // "sig2"
QT_MOC_LITERAL(4, 24, 12), // "sigParam2int" //参数名
QT_MOC_LITERAL(5, 37, 4), // "sig3"
QT_MOC_LITERAL(6, 42, 13), // "sigParam3char"
QT_MOC_LITERAL(7, 56, 12), // "sigParam3int"
QT_MOC_LITERAL(8, 69, 5), // "slot1"
QT_MOC_LITERAL(9, 75, 5), // "slot2"
QT_MOC_LITERAL(10, 81, 10), // "slotParam2"
QT_MOC_LITERAL(11, 92, 5), // "slot3"
QT_MOC_LITERAL(12, 98, 14), // "slotParam3char"
QT_MOC_LITERAL(13, 113, 12), // "slotPram3int"
QT_MOC_LITERAL(14, 126, 10), // "InvokeFunc"
QT_MOC_LITERAL(15, 137, 20), // "InvokeFuncWithReturn"
QT_MOC_LITERAL(16, 158, 17), // "constructIntParam"
QT_MOC_LITERAL(17, 176, 20), // "constructParentParam"
QT_MOC_LITERAL(18, 197, 5) // "prop1"},"ParseQObject\0sig1\0\0sig2\0sigParam2int\0""sig3\0sigParam3char\0sigParam3int\0slot1\0""slot2\0slotParam2\0slot3\0slotParam3char\0""slotPram3int\0InvokeFunc\0InvokeFuncWithReturn\0""constructIntParam\0constructParentParam\0""prop1"
};
#undef QT_MOC_LITERAL
/*/
struct QMetaObjectPrivate
{// revision 7 is Qt 5.0 everything lower is not supported// revision 8 is Qt 5.12: It adds the enum name to QMetaEnumenum { OutputRevision = 8 }; // Used by moc, qmetaobjectbuilder and qdbusint revision;int className;int classInfoCount, classInfoData;int methodCount, methodData;int propertyCount, propertyData;int enumeratorCount, enumeratorData;int constructorCount, constructorData;int flags;int signalCount;
};
/*/
static const uint qt_meta_data_ParseQObject[] = {// content:8, // revision0, // classname 对应QByteArrayData data[19]中的索引0, 0, // classinfo8, 14, // methods 8:信号槽与Q_INVOKABLE函数总数, 14:对应当前数组中的索引1, 82, // properties0, 0, // enums/sets2, 85, // constructors0, // flags3, // signalCount 3:信号总数// signals: name, argc, parameters, tag, flags1, 0, 54, 2, 0x06 /* Public */,// name:1:对应QByteArrayData data[16]中的索引,// argc:0:参数数量,// parameters:49:参数对应当前数组中的索引,// tag:2// flags:0x06:方法类型 0x02 | 0x04/*enum MethodFlags {AccessPrivate = 0x00,AccessProtected = 0x01,AccessPublic = 0x02,AccessMask = 0x03, //maskMethodMethod = 0x00,MethodSignal = 0x04,MethodSlot = 0x08,MethodConstructor = 0x0c,MethodTypeMask = 0x0c,MethodCompatibility = 0x10,MethodCloned = 0x20,MethodScriptable = 0x40,MethodRevisioned = 0x80};*/3, 1, 55, 2, 0x06 /* Public */,5, 2, 58, 2, 0x06 /* Public */,// slots: name, argc, parameters, tag, flags8, 0, 63, 2, 0x0a /* Public */,9, 1, 64, 2, 0x0a /* Public */,11, 2, 67, 2, 0x0a /* Public */,// methods: name, argc, parameters, tag, flags14, 0, 72, 2, 0x02 /* Public */,15, 0, 73, 2, 0x02 /* Public */,// signals: parametersQMetaType::Void,QMetaType::Void, QMetaType::Int, 4,QMetaType::Void, QMetaType::Char, QMetaType::Int, 6, 7,// slots: parameters/*qt_meta_data_ParseQObject[54]*/QMetaType::Void,QMetaType::Void, QMetaType::Int, 10,QMetaType::Void, QMetaType::Char, QMetaType::Int, 12, 13,//返回值类型(Void), 参数类型(Char), 参数类型(Int), 12:data[19]索引, 13:data[19]索引// methods: parametersQMetaType::Void,QMetaType::Int,// constructors: parameters//构造函数类型,因为有默认实参,所以生成使用默认实参,和不使用默认实参两种0x80000000 | 2, QMetaType::Int, QMetaType::QObjectStar, 16, 17,0x80000000 | 2, QMetaType::Int, 16,// properties: name, type, flags18, QMetaType::Int, 0x00095103,//18:data[19]索引, QMetaType::Int 属性类型// constructors: name, argc, parameters, tag, flags0, 2, 74, 2, 0x0e /* Public */,0, 1, 79, 2, 0x2e /* Public | MethodCloned */,0 // eod
};
/*//调用方式enum QMetaObject::Call {InvokeMetaMethod,ReadProperty,WriteProperty,ResetProperty,QueryPropertyDesignable,QueryPropertyScriptable,QueryPropertyStored,QueryPropertyEditable,QueryPropertyUser,CreateInstance,IndexOfMethod,RegisterPropertyMetaType,RegisterMethodArgumentMetaType};
*/
void ParseQObject::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{if (_c == QMetaObject::CreateInstance) {//创建对象switch (_id) {//id为相对索引case 0: { ParseQObject *_r = new ParseQObject((*reinterpret_cast< int(*)>(_a[1])),(*reinterpret_cast< QObject*(*)>(_a[2])));if (_a[0]) *reinterpret_cast<QObject**>(_a[0]) = _r; } break;case 1: { ParseQObject *_r = new ParseQObject((*reinterpret_cast< int(*)>(_a[1])));if (_a[0]) *reinterpret_cast<QObject**>(_a[0]) = _r; } break;default: break;}} else if (_c == QMetaObject::InvokeMetaMethod) {auto *_t = static_cast<ParseQObject *>(_o);Q_UNUSED(_t)switch (_id) {//id为相对索引case 0: _t->sig1(); break;case 1: _t->sig2((*reinterpret_cast< int(*)>(_a[1]))); break;case 2: _t->sig3((*reinterpret_cast< char(*)>(_a[1])),(*reinterpret_cast< int(*)>(_a[2]))); break;case 3: _t->slot1(); break;case 4: _t->slot2((*reinterpret_cast< int(*)>(_a[1]))); break;case 5: _t->slot3((*reinterpret_cast< char(*)>(_a[1])),(*reinterpret_cast< int(*)>(_a[2]))); break;case 6: _t->InvokeFunc(); break;case 7: { int _r = _t->InvokeFuncWithReturn();if (_a[0]) *reinterpret_cast< int*>(_a[0]) = std::move(_r); } break;default: ;}} else if (_c == QMetaObject::IndexOfMethod) {int *result = reinterpret_cast<int *>(_a[0]);{using _t = void (ParseQObject::*)();if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&ParseQObject::sig1)) {*result = 0;return;}}{using _t = void (ParseQObject::*)(int );if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&ParseQObject::sig2)) {*result = 1;return;}}{using _t = void (ParseQObject::*)(char , int );if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&ParseQObject::sig3)) {*result = 2;return;}}}
#ifndef QT_NO_PROPERTIESelse if (_c == QMetaObject::ReadProperty) {//读取属性值auto *_t = static_cast<ParseQObject *>(_o);Q_UNUSED(_t)void *_v = _a[0];switch (_id) {case 0: *reinterpret_cast< int*>(_v) = _t->prop1(); break;default: break;}} else if (_c == QMetaObject::WriteProperty) {//修改属性值auto *_t = static_cast<ParseQObject *>(_o);Q_UNUSED(_t)void *_v = _a[0];switch (_id) {case 0: _t->setProp1(*reinterpret_cast< int*>(_v)); break;default: break;}} else if (_c == QMetaObject::ResetProperty) {}
#endif // QT_NO_PROPERTIES
}
/*
//QMetaObject定义
struct Q_CORE_EXPORT QMetaObject
{struct { // private dataconst QMetaObject *superdata;const QByteArrayData *stringdata;const uint *data;typedef void (*StaticMetacallFunction)(QObject *, QMetaObject::Call, int, void **);StaticMetacallFunction static_metacall;const QMetaObject * const *relatedMetaObjects;void *extradata; //reserved for future use} d;
}
*/
QT_INIT_METAOBJECT const QMetaObject ParseQObject::staticMetaObject = { {&QObject::staticMetaObject, //const QMetaObject *superdata;qt_meta_stringdata_ParseQObject.data, //const QByteArrayData *stringdata;qt_meta_data_ParseQObject, //typedef void (*StaticMetacallFunction)(QObject *, QMetaObject::Call, int, void **);//StaticMetacallFunction static_metacall;qt_static_metacall,nullptr,nullptr
} };const QMetaObject *ParseQObject::metaObject() const
{return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
}void *ParseQObject::qt_metacast(const char *_clname)
{if (!_clname) return nullptr;if (!strcmp(_clname, qt_meta_stringdata_ParseQObject.stringdata0))return static_cast<void*>(this);return QObject::qt_metacast(_clname);
}int ParseQObject::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{_id = QObject::qt_metacall(_c, _id, _a);if (_id < 0)return _id;if (_c == QMetaObject::InvokeMetaMethod) {if (_id < 8)qt_static_metacall(this, _c, _id, _a);_id -= 8;} else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {if (_id < 8)*reinterpret_cast<int*>(_a[0]) = -1;_id -= 8;}
#ifndef QT_NO_PROPERTIESelse if (_c == QMetaObject::ReadProperty || _c == QMetaObject::WriteProperty|| _c == QMetaObject::ResetProperty || _c == QMetaObject::RegisterPropertyMetaType) {qt_static_metacall(this, _c, _id, _a);_id -= 1;} else if (_c == QMetaObject::QueryPropertyDesignable) {_id -= 1;} else if (_c == QMetaObject::QueryPropertyScriptable) {_id -= 1;} else if (_c == QMetaObject::QueryPropertyStored) {_id -= 1;} else if (_c == QMetaObject::QueryPropertyEditable) {_id -= 1;} else if (_c == QMetaObject::QueryPropertyUser) {_id -= 1;}
#endif // QT_NO_PROPERTIESreturn _id;
}// SIGNAL 0
void ParseQObject::sig1()
{QMetaObject::activate(this, &staticMetaObject, 0, nullptr);
}// SIGNAL 1
void ParseQObject::sig2(int _t1)
{//生成信号调用void *_a[] = { nullptr, const_cast<void*>(reinterpret_cast<const void*>(&_t1)) };QMetaObject::activate(this, &staticMetaObject, 1, _a);
}// SIGNAL 2
void ParseQObject::sig3(char _t1, int _t2)
{void *_a[] = { nullptr, const_cast<void*>(reinterpret_cast<const void*>(&_t1)), const_cast<void*>(reinterpret_cast<const void*>(&_t2)) };QMetaObject::activate(this, &staticMetaObject, 2, _a);
}
QT_WARNING_POP
QT_END_MOC_NAMESPACE
Qt Moc 文件解析相关推荐
- QT pro文件解析
在QT中使用qmake自动生成pro文件,如果要自己定制工程选项,则需要自行修改pro文件. pro文件有以下关键字:TEMPLATE.TARGET.DESTDIR.DEPENDPATH.INCLUD ...
- vs生成qt moc文件
1. 右键需要生成moc文件的头文件 2. 将生产的moc加入工程中
- Qt / Moc 和信号 - 槽解析
目录 一. MOC 二. moc_test.cpp 分析 三. connect 四. activate 五. 总结 版本 Qt5.12.3 moc_test.cpp 位于可执行文件目录下,其余源代码都 ...
- Qt工作笔记-undefined reference to `vtable for MyObject'及对moc文件的进一步理解
源码如下: main.cpp #include <QApplication> #include <QObject> #include <QTextCodec>cla ...
- 解决VS+QT无法生成moc文件的问题
解决VS+QT无法生成moc文件的问题 参考文章: (1)解决VS+QT无法生成moc文件的问题 (2)https://www.cnblogs.com/pupilLZT/p/10760399.html ...
- Qt中Q_OBJECT与生成的moc文件的作用
一.先来了解Q_OBJECT 只有继承了QObject类的类,才具有信号槽的能力.所以,为了使用信号槽,必须继承QObject.凡是QObject类(不管是直接子类还是间接子类),都应该在第一行代码写 ...
- VS2015——Qt工程不能生成moc文件的解决办法
问题:在VS2015开发Qt应用程序时发现,编译器提示无法关联信号槽,无法经过moc工具生成相关函数. 解决办法: 1.找到无法生成转换的槽函数头文件,右键头文件(xxx.h)-->找到属性选项 ...
- VS2017 下QT工程不能生成moc文件的解决方法
1.选择要moc的类的头文件,鼠标右键属性,配置属性->常规,在项类型中将C/C++ 标头,改为自定义生成工具 2.左侧点击自定义生成工具,下方的常规,配置如下 命令行:"$(QTDI ...
- Qt pro 文件详解
Qt pro 文件详解 1. TEMPLATE 变量TEMPLATE描述了为建立目标文件而采用何种模板,即生成何种形式的Makefile文件.Qmake 工具定义了5种模板: a. 应用 ...
- qmake language qt 工程文件 配置文件 .pro .prl .prf .pri 词法 语法 for循环 判断语句 函数定义
目录 词法 string 1.数据类型 2.特殊处理的内置变量 3.转义字符 关键字:包括语法关键字.特殊变量 语法 变量 变量.属性.环境变量 变量使用 全局变量作用域 函数定义和使用 判断语句和循 ...
最新文章
- Go 分布式学习利器(8)-- Go的函数
- centos 系统使用verdaccio搭建npm私库
- .NET中属性和特性
- 加上2T硬盘再装系统遇到问题
- Extjs 动态生成表格
- linux解决windows应用程序,关于Linux下使用Windows应用程序的尝试总结
- python规则框架_Pytest框架【2】:用例规则
- 【ArcGIS遇上Python】Python批量将多个文件夹下的多个影像数据镶嵌至新栅格
- (转) Dockerfile 中的 COPY 与 ADD 命令 1
- 第1章 游戏之乐——光影切割问题
- Windows:定时/进程结束执行命令
- NGINX 自动列目录
- 决策树算法 (CART分类树)
- linux版本qq,QQLinux版下载-QQ for Linux下载v2.0.0 最新版-西西软件下载
- 一点笔记,好记性不如烂笔头
- Mac系统中 alt+insert怎么操作?
- 计算机桌面英文翻译,电脑显示器英语怎么说
- java中定义变量名时大写_,【Java】变量命名规范
- 学校计算机培训计划怎么写,学校计算机培训计划_共3篇.doc
- 浏览器必备插件|2022版