Wiki

Clone wiki

libqxt / Meta Object Format

The QMetaObject Format explained

table of contents

Introduction

The generated Code by Moc uses a special internal Format
to introspect a QObject at runtime. This document should help
to understand how that format works.

The data basically consists of two arrays:

  • the qt_meta_data_<Classname> array and
  • the qt_meta_stringdata_<Classname> array.

In the qt_meta_stringdata array moc puts all the method, parameter, slot, signal.... names as stringdata.
The strings are referenced over a index in the qt_meta_data array.

In the qt_meta_data array moc creates a own line for every QMeta related item.
Some of them just reference strings in the stringdata, some also have some flags
that describe the items in a greater depth.

Example

I will use a example to descibe how them exactly work:

static const uint qt_meta_data_Testclass[] = {

 // content:
       4,       // revision
       0,       // classname
       2,   14, // classinfo
       9,   18, // methods
       1,   63, // properties
       2,   66, // enums/sets
       2,   86, // constructors
       0,       // flags
       4,       // signalCount

 // classinfo: key, value
      20,   10,
      42,   27,

 // signals: signature, parameters, type, tag, flags
      54,   53,   53,   53, 0x05,
      76,   71,   67,   53, 0x05,
     107,   97,   53,   53, 0x05,
     132,   71,   53,   53, 0x25,

 // slots: signature, parameters, type, tag, flags
     164,  153,   67,   53, 0x0a,
     195,  190,   67,   53, 0x2a,
     222,   53,  213,   53, 0x0a,

 // methods: signature, parameters, type, tag, flags
     239,   53,   53,   53, 0x02,
     256,   53,   53,   53, 0x02,

 // properties: name, type, flags
     273,  265, 0x0a095107,

 // enums: name, flags, count, data
     279, 0x0,    4,   74,
     292, 0x0,    2,   82,

 // enum data: key, value
     304, uint(Testclass::aep),
      10, uint(Testclass::zbenjamin),
     308, uint(Testclass::ahigerd),
     316, uint(Testclass::jpnurmi),
     324, uint(Testclass::bhughes),
     332, uint(Testclass::icefox),

 // constructors: signature, parameters, type, tag, flags
     356,  339,   53,   53, 0x0e,
     388,   97,   53,   53, 0x2e,

       0        // eod
};

static const char qt_meta_stringdata_Testclass[] = {
    "Testclass\0zbenjamin\0author\0Qxt Foundation\0"  41
    "foundation\0\0testSignal()\0int\0arg1\0"
    "returningSignal(int)\0arg1,arg2\0"
    "signalWithArgs(int&,int)\0signalWithArgs(int&)\0"
    "test,test2\0testSlot(QString,QString)\0"
    "test\0testSlot(QString)\0QObject*\0"
    "createInstance()\0emitTestSignal()\0"
    "noSlot()\0QString\0title\0QxtStaffEnum\0"
    "QtStaffEnum\0aep\0ahigerd\0jpnurmi\0bhughes\0"
    "icefox\0arg1,arg2,parent\0"
    "Testclass(int,QString,QObject*)\0"
    "Testclass(int,QString)\0"
};

Header of qt_meta_data

Lets have a look at the header of qt_meta_data:
The header tells us how many metaobject items exists
and where we can find their description in the qt_meta_data array.

explanation
4,revision of the metobject compiler, everytime the Qt devs change the layout of the created files this
number also changes, to maintain backwards compatibility
0,Offset of the classname in the stringdata ( in this case "Testclass" )
2,14,The first value tells us how many Q_CLASSINFO's are available in this QMetaObject
The second value tells us the offset in qt_meta_data where moc puts the first Q_CLASSINFO description
9,18,count and offset of methods in qt_meta_data (this includes signals, slots and invokables)
1,63,count and offset of properties in qt_meta_data
2,66,count and offset of enums/sets in qt_meta_data
2,86,count and offset of constructors in qt_meta_data
0,the QMetaObject flags
4,signalCount , tells moc the number of methods that are signals

Q_CLASSINFO items

directly after the header moc puts all Q_CLASSINFO's in a row:

 // classinfo: key, value
      20,   10,
      42,   27,

The first value is the offset of the keyname in the stringdata array, the second one is the value, also a reference to stringdata. The first item for example references the classinfo: key: author value: zbenjamin

Method items

After the Q_CLASSINFO items moc adds all methods.
First signals, then slots and methods.
All method items are build in the same way:

signatueparameterstypetagflags
54,53,53,53,0x05,
76,71,67,53,0x05,
107,97,53,53,0x05,
132,71,53,53,0x25,

Every column explained:

nameexplanation
signatureThis is the offset of the stringdata in the qt_meta_stringdata array
For example testSignal() for the first signal with offset 54
parametersThis is the offset for the parameter NAMES in the qt_meta_stringdata array
For example arg1 for the second signal with offset 71
typeThis is the offset of the RETURN TYPE NAME in the qt_meta_stringdata array
All methods in our example have no return type, thats why all offsets point to \0
tagNo idea yet
flagsThis is a combination of internal flags

Internal method flags

This is the internal enum of the method flags, they can be or'ed together.

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
};

Most of them are self explanatory, except the last three values.

MethodCloned Flag

The method cloned flag is a special and really important flag.
To handle default values in function parameters, like int foo ( int a, int b = 20 ) ,
moc needs to create a own "clone" for every default Parameter.
In our example moc first adds the real function with the signature foo (int,int) and then all the clones ,
in this case only foo ( int ), in a row.
Its extremely important that all Clones of a method are sequentially added after the original method.
To mark those Clones moc will or this flag to the MethodFlags in th qt_meta_data array

MethodCompatibility

No idea yet

MethodScriptable

No idea yet

Property items

The next items in the list are the property items. You can define Properties with the Q_PROPERTY keyword.

In our example we have only one property, it looks like:

nametypeflags
2732650x0a095107

Every column explained:

nameexplanation
nameThe offset of the property name string: "title\0"
typeThe offset of the type string , "QString\0"
flagsThe flags that describe the property

Following internal Flags are available for properties:

    enum PropertyFlags  {
        Invalid = 0x00000000,
        Readable = 0x00000001,
        Writable = 0x00000002,
        Resettable = 0x00000004,
        EnumOrFlag = 0x00000008,
        StdCppSet = 0x00000100,
        Constant = 0x00000400,
        Final = 0x00000800,
        Designable = 0x00001000,
        ResolveDesignable = 0x00002000,
        Scriptable = 0x00004000,
        ResolveScriptable = 0x00008000,
        Stored = 0x00010000,
        ResolveStored = 0x00020000,
        Editable = 0x00040000,
        ResolveEditable = 0x00080000,
        User = 0x00100000,
        ResolveUser = 0x00200000,
        Notify = 0x00400000
    };

Some of the flags are set using the Q_PROPERTY macro available for all QObjects. Others are set by moc.

Enum items

Work in progress

Constructor items

Work in progress

Updated