龙空技术网

Qt Core学习日记——第七天QMetaObject(上)

嗷呜笨 120

前言:

今天同学们对“无法解析外部符号qmetaobject”都比较珍视,姐妹们都想要知道一些“无法解析外部符号qmetaobject”的相关内容。那么小编同时在网上收集了一些有关“无法解析外部符号qmetaobject””的相关文章,希望同学们能喜欢,朋友们快快来了解一下吧!

每一个声明Q_OBJECT的类都具有QMetaObject对象

Q_OBJECT宏源代码:

#define Q_OBJECT \public: \QT_WARNING_PUSH \Q_OBJECT_NO_OVERRIDE_WARNING \static const QMetaObject staticMetaObject; \virtual const QMetaObject *metaObject() const; \virtual void *qt_metacast(const char *); \virtual int qt_metacall(QMetaObject::Call, int, void **); \QT_TR_FUNCTIONS \private: \Q_OBJECT_NO_ATTRIBUTES_WARNING \Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); \QT_WARNING_POP \struct QPrivateSignal {}; \QT_ANNOTATE_CLASS(qt_qobject, "")

每一个声明Q_OBJECT类的对象都具有同一静态成员staticMetaObject,staticMetaObject用于存储类的基础信息,比如类属性、类信息。

例如类XTest的QMetaObject staticMetaObject

XTest::staticMetaObject中包含类信息"author", "Sabrina Schweinsteiger",类属性autoStartup,槽函数、信号、其它函数

XTest.h

#pragma once#include <qobject.h>#include <QFlags>class XTest : public QObject{Q_OBJECTQ_CLASSINFO("author", "Sabrina Schweinsteiger")Q_PROPERTY(bool autoStartup READ autoStartup WRITE setAutoStartup NOTIFY sigAutoStartup)public:XTest(QObject* p = nullptr) {}~XTest() {}public:enum Priority{High,Low,VeryHigh,VeryLow};Q_ENUM(Priority)enum PriorityFlag{High1,Low1,VeryHigh1,VeryLow1};Q_FLAG(PriorityFlag)Q_DECLARE_FLAGS(Alignment, PriorityFlag)Q_FLAG(Alignment)public:bool autoStartup() { return m_autoStartup; }void setAutoStartup(bool b) { m_autoStartup = b; emit sigAutoStartup(); }public slots:void slot1(double* p1) {}Q_INVOKABLE void slot2(int* p2) {}Q_REVISION(1) void slot3(char* p3) {}Q_INVOKABLE void slot4(int p2, double) {}signals:void sig1(void * p4);void sigAutoStartup();private:Q_REVISION(1) bool m_autoStartup = false;};

XTest.cpp:

#include "XTest.h"

qt生成的moc文件moc_XTest.cpp:

/****************************************************************************** Meta object code from reading C++ file 'XTest.h'**** Created by: The Qt Meta Object Compiler version 67 (Qt 5.15.2)**** WARNING! All changes made in this file will be lost!*****************************************************************************/#include <memory>#include "../../../XTest.h"#include <QtCore/qbytearray.h>#include <QtCore/qmetatype.h>#if !defined(Q_MOC_OUTPUT_REVISION)#error "The header file 'XTest.h' doesn't include <QObject>."#elif Q_MOC_OUTPUT_REVISION != 67#error "This file was generated using the moc from 5.15.2. It"#error "cannot be used with the include files from this version of Qt."#error "(The moc has changed too much.)"#endifQT_BEGIN_MOC_NAMESPACEQT_WARNING_PUSHQT_WARNING_DISABLE_DEPRECATEDstruct qt_meta_stringdata_XTest_t {QByteArrayData data[29];char stringdata0[212];};#define QT_MOC_LITERAL(idx, ofs, len) \Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \qptrdiff(offsetof(qt_meta_stringdata_XTest_t, stringdata0) + ofs \- idx * sizeof(QByteArrayData)) \)static const qt_meta_stringdata_XTest_t qt_meta_stringdata_XTest = {{QT_MOC_LITERAL(0, 0, 5), // "XTest"QT_MOC_LITERAL(1, 6, 6), // "author"QT_MOC_LITERAL(2, 13, 22), // "Sabrina Schweinsteiger"QT_MOC_LITERAL(3, 36, 4), // "sig1"QT_MOC_LITERAL(4, 41, 0), // ""QT_MOC_LITERAL(5, 42, 2), // "p4"QT_MOC_LITERAL(6, 45, 14), // "sigAutoStartup"QT_MOC_LITERAL(7, 60, 5), // "slot1"QT_MOC_LITERAL(8, 66, 7), // "double*"QT_MOC_LITERAL(9, 74, 2), // "p1"QT_MOC_LITERAL(10, 77, 5), // "slot2"QT_MOC_LITERAL(11, 83, 4), // "int*"QT_MOC_LITERAL(12, 88, 2), // "p2"QT_MOC_LITERAL(13, 91, 5), // "slot3"QT_MOC_LITERAL(14, 97, 5), // "char*"QT_MOC_LITERAL(15, 103, 2), // "p3"QT_MOC_LITERAL(16, 106, 5), // "slot4"QT_MOC_LITERAL(17, 112, 11), // "autoStartup"QT_MOC_LITERAL(18, 124, 8), // "Priority"QT_MOC_LITERAL(19, 133, 4), // "High"QT_MOC_LITERAL(20, 138, 3), // "Low"QT_MOC_LITERAL(21, 142, 8), // "VeryHigh"QT_MOC_LITERAL(22, 151, 7), // "VeryLow"QT_MOC_LITERAL(23, 159, 12), // "PriorityFlag"QT_MOC_LITERAL(24, 172, 5), // "High1"QT_MOC_LITERAL(25, 178, 4), // "Low1"QT_MOC_LITERAL(26, 183, 9), // "VeryHigh1"QT_MOC_LITERAL(27, 193, 8), // "VeryLow1"QT_MOC_LITERAL(28, 202, 9) // "Alignment"},"XTest\0author\0Sabrina Schweinsteiger\0""sig1\0\0p4\0sigAutoStartup\0slot1\0double*\0""p1\0slot2\0int*\0p2\0slot3\0char*\0p3\0slot4\0""autoStartup\0Priority\0High\0Low\0VeryHigh\0""VeryLow\0PriorityFlag\0High1\0Low1\0""VeryHigh1\0VeryLow1\0Alignment"};#undef QT_MOC_LITERALstatic const uint qt_meta_data_XTest[] = {// content:8, // revision0, // classname1, 14, // classinfo6, 16, // methods1, 70, // properties3, 74, // enums/sets0, 0, // constructors0, // flags2, // signalCount// classinfo: key, value1, 2,// signals: name, argc, parameters, tag, flags3, 1, 52, 4, 0x06 /* Public */,6, 0, 55, 4, 0x06 /* Public */,// slots: name, argc, parameters, tag, flags7, 1, 56, 4, 0x0a /* Public */,10, 1, 59, 4, 0x0a /* Public */,13, 1, 62, 4, 0x8a /* Public | MethodRevisioned */,16, 2, 65, 4, 0x0a /* Public */,// signals: revision0,0,// slots: revision0,0,1,0,// signals: parametersQMetaType::Void, QMetaType::VoidStar, 5,QMetaType::Void,// slots: parametersQMetaType::Void, 0x80000000 | 8, 9,QMetaType::Void, 0x80000000 | 11, 12,QMetaType::Void, 0x80000000 | 14, 15,QMetaType::Void, QMetaType::Int, QMetaType::Double, 12, 4,// properties: name, type, flags17, QMetaType::Bool, 0x00495103,// properties: notify_signal_id1,// enums: name, alias, flags, count, data18, 18, 0x0, 4, 89,23, 23, 0x1, 4, 97,28, 23, 0x1, 4, 105,// enum data: key, value19, uint(XTest::High),20, uint(XTest::Low),21, uint(XTest::VeryHigh),22, uint(XTest::VeryLow),24, uint(XTest::High1),25, uint(XTest::Low1),26, uint(XTest::VeryHigh1),27, uint(XTest::VeryLow1),24, uint(XTest::High1),25, uint(XTest::Low1),26, uint(XTest::VeryHigh1),27, uint(XTest::VeryLow1),0 // eod};void XTest::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a){if (_c == QMetaObject::InvokeMetaMethod) {auto *_t = static_cast<XTest *>(_o);Q_UNUSED(_t)switch (_id) {case 0: _t->sig1((*reinterpret_cast< void*(*)>(_a[1]))); break;case 1: _t->sigAutoStartup(); break;case 2: _t->slot1((*reinterpret_cast< double*(*)>(_a[1]))); break;case 3: _t->slot2((*reinterpret_cast< int*(*)>(_a[1]))); break;case 4: _t->slot3((*reinterpret_cast< char*(*)>(_a[1]))); break;case 5: _t->slot4((*reinterpret_cast< int(*)>(_a[1])),(*reinterpret_cast< double(*)>(_a[2]))); break;default: ;}} else if (_c == QMetaObject::IndexOfMethod) {int *result = reinterpret_cast<int *>(_a[0]);{using _t = void (XTest::*)(void * );if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&XTest::sig1)) {*result = 0;return;}}{using _t = void (XTest::*)();if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&XTest::sigAutoStartup)) {*result = 1;return;}}}#ifndef QT_NO_PROPERTIESelse if (_c == QMetaObject::ReadProperty) {auto *_t = static_cast<XTest *>(_o);Q_UNUSED(_t)void *_v = _a[0];switch (_id) {case 0: *reinterpret_cast< bool*>(_v) = _t->autoStartup(); break;default: break;}} else if (_c == QMetaObject::WriteProperty) {auto *_t = static_cast<XTest *>(_o);Q_UNUSED(_t)void *_v = _a[0];switch (_id) {case 0: _t->setAutoStartup(*reinterpret_cast< bool*>(_v)); break;default: break;}} else if (_c == QMetaObject::ResetProperty) {}#endif // QT_NO_PROPERTIES}QT_INIT_METAOBJECT const QMetaObject XTest::staticMetaObject = { {QMetaObject::SuperData::link<QObject::staticMetaObject>(),qt_meta_stringdata_XTest.data,qt_meta_data_XTest,qt_static_metacall,nullptr,nullptr} };const QMetaObject *XTest::metaObject() const{return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;}void *XTest::qt_metacast(const char *_clname){if (!_clname) return nullptr;if (!strcmp(_clname, qt_meta_stringdata_XTest.stringdata0))return static_cast<void*>(this);return QObject::qt_metacast(_clname);}int XTest::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 < 6)qt_static_metacall(this, _c, _id, _a);_id -= 6;} else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {if (_id < 6)*reinterpret_cast<int*>(_a[0]) = -1;_id -= 6;}#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 0void XTest::sig1(void * _t1){void *_a[] = { nullptr, const_cast<void*>(reinterpret_cast<const void*>(std::addressof(_t1))) };QMetaObject::activate(this, &staticMetaObject, 0, _a);}// SIGNAL 1void XTest::sigAutoStartup(){QMetaObject::activate(this, &staticMetaObject, 1, nullptr);}QT_WARNING_POPQT_END_MOC_NAMESPACE

函数解析:

静态函数

bool QMetaObject::checkConnectArgs(const char *signal, const char *method)

检查2个字符串参数是否相同。传入参数字符串需要是QMetaObject::normalizedSignature返回的字符串。例如slots2函数签名是“slots2(int*)”。就是上一篇QMetaMethod::methodSignature函数返回值

bool QMetaObject::checkConnectArgs(const QMetaMethod &signal, const QMetaMethod &method)

检查信号与槽参数连接参数是否相同

QByteArray QMetaObject::normalizedSignature

获取函数签名。例如slots2函数签名是“slots2(int*)”。就是上一篇QMetaMethod::methodSignature函数返回值

标签: #无法解析外部符号qmetaobject