Wiki
Clone wikilibqxt / 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:
signatue | parameters | type | tag | flags |
---|---|---|---|---|
54, | 53, | 53, | 53, | 0x05, |
76, | 71, | 67, | 53, | 0x05, |
107, | 97, | 53, | 53, | 0x05, |
132, | 71, | 53, | 53, | 0x25, |
Every column explained:
name | explanation |
---|---|
signature | This is the offset of the stringdata in the qt_meta_stringdata array For example testSignal() for the first signal with offset 54 |
parameters | This is the offset for the parameter NAMES in the qt_meta_stringdata array For example arg1 for the second signal with offset 71 |
type | This 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 |
tag | No idea yet |
flags | This 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:
name | type | flags |
---|---|---|
273 | 265 | 0x0a095107 |
Every column explained:
name | explanation |
---|---|
name | The offset of the property name string: "title\0" |
type | The offset of the type string , "QString\0" |
flags | The 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