Qt(2):MOC文件解析

 在Qt下,从QObject派生的类都会生成moc_文件。

1. 比如现在有2个文件,qmyobject.h和qmyobject.cpp,它里面有一个类QMyObject,记为版本A

class QMyObject : public QObject
{
    Q_OBJECT

public:
    QMyObject(QObject *parent);
    ~QMyObject();        
};

然后我们给其添加一个信号和一个槽函数,即修改后的qmyobject.h的内容如下,记为版本B。

class QMyObject : public QObject
{
    Q_OBJECT

public:
    QMyObject(QObject *parent);
    ~QMyObject();
    
signals:
    void signalFunc(double);

protected slots:
    void slotFunc(double);
};

下面给出2个这2个版本的moc文件

未添加signal/slot添加了signal/slot
/****************************************************************************
** Meta object code from reading C++ file 'qmyobject.h'
**
** Created by: The Qt Meta Object Compiler version 67 (Qt 5.2.1)
**
** WARNING! All changes made in this file will be lost!
*****************************************************************************/

#include "../../qmyobject.h"
#include <QtCore/qbytearray.h>
#include <QtCore/qmetatype.h>
#if !defined(Q_MOC_OUTPUT_REVISION)
#error "The header file 'qmyobject.h' doesn't include <QObject>."
#elif Q_MOC_OUTPUT_REVISION != 67
#error "This file was generated using the moc from 5.2.1. It"
#error "cannot be used with the include files from this version of Qt."
#error "(The moc has changed too much.)"
#endif

QT_BEGIN_MOC_NAMESPACE
<span style="color:#ff0000;">struct qt_meta_stringdata_QMyObject_t {
    QByteArrayData data[1];
    char stringdata[11];
};</span>
#define QT_MOC_LITERAL(idx, ofs, len) \
    Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
    offsetof(qt_meta_stringdata_QMyObject_t, stringdata) + ofs \
        - idx * sizeof(QByteArrayData) \
    )
<span style="color:#ff0000;">static const qt_meta_stringdata_QMyObject_t qt_meta_stringdata_QMyObject = {
    {
QT_MOC_LITERAL(0, 0, 9)
    },
    "QMyObject\0"
};</span>
#undef QT_MOC_LITERAL

<span style="color:#ff0000;">static const uint qt_meta_data_QMyObject[] = {

 // content:
       7,       // revision
       0,       // classname
       0,    0, // classinfo
       0,    0, // methods
       0,    0, // properties
       0,    0, // enums/sets
       0,    0, // constructors
       0,       // flags
       0,       // signalCount

       0        // eod
};</span>

<span style="color:#ff0000;">void QMyObject::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
    Q_UNUSED(_o);
    Q_UNUSED(_id);
    Q_UNUSED(_c);
    Q_UNUSED(_a);
}</span>

const QMetaObject QMyObject::staticMetaObject = {
    { &QObject::staticMetaObject, qt_meta_stringdata_QMyObject.data,
      qt_meta_data_QMyObject,  qt_static_metacall, 0, 0}
};


const QMetaObject *QMyObject::metaObject() const
{
    return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
}

void *QMyObject::qt_metacast(const char *_clname)
{
    if (!_clname) return 0;
    if (!strcmp(_clname, qt_meta_stringdata_QMyObject.stringdata))
        return static_cast<void*>(const_cast< QMyObject*>(this));
    return QObject::qt_metacast(_clname);
}

<span style="color:#ff0000;">int QMyObject::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
    _id = QObject::qt_metacall(_c, _id, _a);
    if (_id < 0)
        return _id;
    return _id;
}</span>
QT_END_MOC_NAMESPACE

/****************************************************************************
** Meta object code from reading C++ file 'qmyobject.h'
**
** Created by: The Qt Meta Object Compiler version 67 (Qt 5.2.1)
**
** WARNING! All changes made in this file will be lost!
*****************************************************************************/

#include "../../qmyobject.h"
#include <QtCore/qbytearray.h>
#include <QtCore/qmetatype.h>
#if !defined(Q_MOC_OUTPUT_REVISION)
#error "The header file 'qmyobject.h' doesn't include <QObject>."
#elif Q_MOC_OUTPUT_REVISION != 67
#error "This file was generated using the moc from 5.2.1. It"
#error "cannot be used with the include files from this version of Qt."
#error "(The moc has changed too much.)"
#endif

QT_BEGIN_MOC_NAMESPACE
<span style="color:#ff0000;">struct qt_meta_stringdata_QMyObject_t {
    QByteArrayData data[4];
    char stringdata[32];
};</span>
#define QT_MOC_LITERAL(idx, ofs, len) \
    Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
    offsetof(qt_meta_stringdata_QMyObject_t, stringdata) + ofs \
        - idx * sizeof(QByteArrayData) \
    )
<span style="color:#ff0000;">static const qt_meta_stringdata_QMyObject_t qt_meta_stringdata_QMyObject = {
    {
QT_MOC_LITERAL(0, 0, 9),
QT_MOC_LITERAL(1, 10, 10),
QT_MOC_LITERAL(2, 21, 0),
QT_MOC_LITERAL(3, 22, 8)
    },
    "QMyObject\0signalFunc\0\0slotFunc\0"
};</span>
#undef QT_MOC_LITERAL

<span style="color:#ff0000;">static const uint qt_meta_data_QMyObject[] = {

 // content:
       7,       // revision
       0,       // classname
       0,    0, // classinfo
       2,   14, // methods
       0,    0, // properties
       0,    0, // enums/sets
       0,    0, // constructors
       0,       // flags
       1,       // signalCount

 // signals: name, argc, parameters, tag, flags
       1,    1,   24,    2, 0x06,

 // slots: name, argc, parameters, tag, flags
       3,    1,   27,    2, 0x09,

 // signals: parameters
    QMetaType::Void, QMetaType::Double,    2,

 // slots: parameters
    QMetaType::Void, QMetaType::Double,    2,

       0        // eod
};</span>

<span style="color:#ff0000;">void QMyObject::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
    if (_c == QMetaObject::InvokeMetaMethod) {
        QMyObject *_t = static_cast<QMyObject *>(_o);
        switch (_id) {
        case 0: _t->signalFunc((*reinterpret_cast< double(*)>(_a[1]))); break;
        case 1: _t->slotFunc((*reinterpret_cast< double(*)>(_a[1]))); break;
        default: ;
        }
    } else if (_c == QMetaObject::IndexOfMethod) {
        int *result = reinterpret_cast<int *>(_a[0]);
        void **func = reinterpret_cast<void **>(_a[1]);
        {
            typedef void (QMyObject::*_t)(double );
            if (*reinterpret_cast<_t *>(func) == static_cast<_t>(&QMyObject::signalFunc)) {
                *result = 0;
            }
        }
    }
}</span>

const QMetaObject QMyObject::staticMetaObject = {
    { &QObject::staticMetaObject, qt_meta_stringdata_QMyObject.data,
      qt_meta_data_QMyObject,  qt_static_metacall, 0, 0}
};


const QMetaObject *QMyObject::metaObject() const
{
    return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
}

void *QMyObject::qt_metacast(const char *_clname)
{
    if (!_clname) return 0;
    if (!strcmp(_clname, qt_meta_stringdata_QMyObject.stringdata))
        return static_cast<void*>(const_cast< QMyObject*>(this));
    return QObject::qt_metacast(_clname);
}

<span style="color:#ff0000;">int QMyObject::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 < 2)
            qt_static_metacall(this, _c, _id, _a);
        _id -= 2;
    } else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
        if (_id < 2)
            *reinterpret_cast<int*>(_a[0]) = -1;
        _id -= 2;
    }
    return _id;
}</span>

<strong><span style="color:#ff0000;">// SIGNAL 0
void QMyObject::signalFunc(double _t1)
{
    void *_a[] = { 0, const_cast<void*>(reinterpret_cast<const void*>(&_t1)) };
    QMetaObject::activate(this, &staticMetaObject, 0, _a);
}</span></strong>
QT_END_MOC_NAMESPACE


在右边一栏:

qt_meta_stringdata_QMyObject_t:

代表QMyObject中的函数名。


qt_meta_data_QMyObject:

methods部分前面的2代表此类中信号和槽总数为2,14代表qt_meta_data_QMyObject中的content的个数,一共有14个,对应着QMetaObjectPrivate变量的14个成员变量。 

信号前面的是1,而槽前面的是3,在看看

<span style="color:#ff0000;">"QMyObject\0signalFunc\0\0slotFunc\0"</span>

我们如果以\0作为索引,一对比就知道signalFunc的索引为1,而slotFunc的索引为3。


然后看看源对象定义:

const QMetaObject myClass::staticMetaObject = {
    { &QObject::staticMetaObject, qt_meta_stringdata_myClass,
      qt_meta_data_myClass, 0 }
};
可以看到源对象的数据定义为:
    struct { // private data
        const QMetaObject *superdata;
        const char *stringdata;
        const uint *data;
        const void *extradata;
    }









参考:

1. http://blog.csdn.net/smad732/article/details/6107448#

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值