当前位置: 首页 > 工具软件 > MOC > 使用案例 >

Qt Moc 文件解析

温源
2023-12-01

Moc文件内容

Moc 文件是Qt moc工具生成的实现文件,用于实现Qt的元对象系统

类原始代码

class ParseQObject : public QObject
{
    Q_OBJECT
    Q_PROPERTY(int prop1 READ prop1 WRITE setProp1)// 属性1
public:
    explicit ParseQObject(QObject *parent = nullptr);
    //can create instance constructor 1
    Q_INVOKABLE ParseQObject(int constructIntParam, QObject *constructParentParam = nullptr);
signals:
    void sig1();//信号1
    void sig2(int sigParam2int);//信号2
    void sig3(char sigParam3char, int sigParam3int);//信号3
public slots:
    void slot1();//槽1
    void slot2(int slotParam2);//槽2
    void slot3(char slotParam3char, int slotPram3int);//槽3

public:
    Q_INVOKABLE void InvokeFunc();//invoke function 1
    Q_INVOKABLE int InvokeFuncWithReturn();//invoke func 2
    int 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 header
	
	void *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*16
	sig_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 
					
					sig2
					sigParam2int
					sig3
					sigParam3char
					sigParam3int
					slot1
					slot2
					slotParam2
					slot3
					slotParam3char
					slotPram3int
					InvokeFunc
	data[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 QMetaEnum
    enum { OutputRevision = 8 }; // Used by moc, qmetaobjectbuilder and qdbus

    int 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,       // revision
       0,       // classname	对应QByteArrayData data[19]中的索引
       0,    0, // classinfo
       8,   14, // methods		8:信号槽与Q_INVOKABLE函数总数, 14:对应当前数组中的索引
       1,   82, // properties
       0,    0, // enums/sets
       2,   85, // constructors
       0,       // flags
       3,       // signalCount	3:信号总数

 // signals: name, argc, parameters, tag, flags
       		  1,    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, //mask
		 
			MethodMethod = 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, flags
       8,    0,   63,    2, 0x0a /* Public */,
       9,    1,   64,    2, 0x0a /* Public */,
      11,    2,   67,    2, 0x0a /* Public */,

 // methods: name, argc, parameters, tag, flags
      14,    0,   72,    2, 0x02 /* Public */,
      15,    0,   73,    2, 0x02 /* Public */,

 // signals: parameters
    QMetaType::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: parameters
    QMetaType::Void,
    QMetaType::Int,

 // constructors: parameters
 //构造函数类型,因为有默认实参,所以生成使用默认实参,和不使用默认实参两种
    0x80000000 | 2, QMetaType::Int, QMetaType::QObjectStar,   16,   17,
    0x80000000 | 2, QMetaType::Int,   16,

 // properties: name, type, flags
      18, 					QMetaType::Int, 		0x00095103,
	//18:data[19]索引,		QMetaType::Int 属性类型

 // constructors: name, argc, parameters, tag, flags
       0,    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_PROPERTIES
    else 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 data
		const 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_PROPERTIES
    else 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_PROPERTIES
    return _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
 类似资料: