Qt 之实用程序 moc 学习
2011-08-06 11:56
471 查看
本文关注Qt的工具程序 moc 本身。
moc : 元对象编译器(Meta-Object Compiler)
运行 moc -h 或者查看Manual关注几个选项:
其中:
-D -U
定义和反定义宏, (注:内部默认定义Q_MOC_RUN和__cplusplus两个宏)
-i -f
控制是否包含include语句,默认是自动(对比Q_OBJECT这个宏分别出现在*.h和*.cpp时生成的文件的不同)
moc 的处理分两个阶段(共3个步骤):
Preprocessor
Moc
parse
generate
lexical analysis
moc 将输入文件解析成一个 Token (即symbols) 的列表
词法分析的基础是一个有限状态机(fix me?),源码位于 $QTDIR/src/tools/moc 下的
keywords.cpp
ppkeywords.cpp
这两个文件是由$QTDIR/src/tools/moc/util下的工具程序生成的,generate_keywords.cpp 文件中是原始的(可读的) 关键词和Token的对应关系
在 Tokenization 之后,需要parse某些我们关注的Token,此时需要处理Token之间的关系。
比如:对于 Q_DECLARE_METATYPE
对于 signals
将metatype信息转换成代码并输出是通过另一个类来完成的:
从类定义大致可以猜出它做了什么
http://doc.qt.nokia.com/4.7/moc.html
moc : 元对象编译器(Meta-Object Compiler)
命令行选项
moc -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4 -I. -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED hled.h -o moc_hled.cpp
运行 moc -h 或者查看Manual关注几个选项:
-I<dir> | add dir to the include path for header files |
-E | preprocess only; do not generate meta object code |
-D<macro>[=<def>] | define macro, with optional definition |
-U<macro> | undefine macro |
-i | do not generate an #include statement |
-p<path> | path prefix for included file |
-f[<file>] | force #include, optional file name |
-D -U
定义和反定义宏, (注:内部默认定义Q_MOC_RUN和__cplusplus两个宏)
-i -f
控制是否包含include语句,默认是自动(对比Q_OBJECT这个宏分别出现在*.h和*.cpp时生成的文件的不同)
moc 的处理分两个阶段(共3个步骤):
Preprocessor
Moc
parse
generate
Preprocessor pp; Moc moc; pp.macros["Q_MOC_RUN"]; pp.macros["__cplusplus"]; ... // 1. preprocess moc.symbols = pp.preprocessed(moc.filename, in); fclose(in); if (!pp.preprocessOnly) { // 2. parse moc.parse(); } // 3. and output meta object code if (pp.preprocessOnly) { fprintf(out, "%s\n", composePreprocessorOutput(moc.symbols).constData()); } else { moc.generate(out); }
词法分析
lexical analysismoc 将输入文件解析成一个 Token (即symbols) 的列表
moc.symbols = pp.preprocessed(moc.filename, in);
词法分析的基础是一个有限状态机(fix me?),源码位于 $QTDIR/src/tools/moc 下的
keywords.cpp
ppkeywords.cpp
这两个文件是由$QTDIR/src/tools/moc/util下的工具程序生成的,generate_keywords.cpp 文件中是原始的(可读的) 关键词和Token的对应关系
... { "while", "WHILE" }, { "do", "DO" }, { "for", "FOR" }, { "break", "BREAK" }, { "continue", "CONTINUE" }, { "goto", "GOTO" }, { "return", "RETURN" }, { "Q_OBJECT", "Q_OBJECT_TOKEN" }, { "Q_GADGET", "Q_GADGET_TOKEN" }, { "Q_PROPERTY", "Q_PROPERTY_TOKEN" }, { "Q_ENUMS", "Q_ENUMS_TOKEN" }, { "Q_FLAGS", "Q_FLAGS_TOKEN" }, { "Q_DECLARE_FLAGS", "Q_DECLARE_FLAGS_TOKEN" }, { "Q_DECLARE_INTERFACE", "Q_DECLARE_INTERFACE_TOKEN" }, ...
语法分析(?)
在 Tokenization 之后,需要parse某些我们关注的Token,此时需要处理Token之间的关系。moc.parse();
比如:对于 Q_DECLARE_METATYPE
void Moc::parseDeclareMetatype() { next(LPAREN); QByteArray typeName = lexemUntil(RPAREN); typeName.remove(0, 1); typeName.chop(1); metaTypes.append(typeName); }
对于 signals
void Moc::parseSignals(ClassDef *def) { next(COLON); while (inClass(def) && hasNext()) { ... FunctionDef funcDef; funcDef.access = FunctionDef::Protected; parseFunction(&funcDef); if (funcDef.isVirtual) warning("Signals cannot be declared virtual"); if (funcDef.inlineCode) error("Not a signal declaration"); def->signalList += funcDef; while (funcDef.arguments.size() > 0 && funcDef.arguments.last().isDefault) { funcDef.wasCloned = true; funcDef.arguments.removeLast(); def->signalList += funcDef; } } }
output
moc.generate(out);
将metatype信息转换成代码并输出是通过另一个类来完成的:
for (i = 0; i < classList.size(); ++i) { Generator generator(&classList[i], metaTypes, out); generator.generateCode(); }
从类定义大致可以猜出它做了什么
class Generator { FILE *out; ClassDef *cdef; QVector<uint> meta_data; public: Generator(ClassDef *classDef, const QList<QByteArray> &metaTypes, FILE *outfile = 0); void generateCode(); QMetaObject *generateMetaObject(bool ignoreProperties); private: void generateClassInfos(); void generateFunctions(QList<FunctionDef> &list, const char *functype, int type); void generateEnums(int index); void generateProperties(); void generateMetacall(); void generateStaticMetacall(const QByteArray &prefix); void generateSignal(FunctionDef *def, int index); ...
参考
http://doc.qt.nokia.com/4.7/moc.html
相关文章推荐
- Qt 之实用程序 moc 学习
- QT moc 学习小结
- Qt自动生成moc文件
- Qt简介以及如何配置Qt使用VS2010进行开发 分类: QT学习实践 2015-05-05 16:02 34人阅读 评论(0) 收藏
- QT无法编译#include *.moc的项目,报No such file or directory
- Qt学习中遇到的问题
- Qt学习:项视图类之QStringListModel和QListView
- 学习记录-Qt窗口控件的动态添加和删除
- qt学习笔记(七)之数据库简介
- QT学习之路————使用QT自带的QSqlDatabase类简单操作sqlite数据库
- Qt 学习之路 2(44):QFileSystemModel
- 嵌入式Qt开发环境搭建及移植到开发板----Qt学习笔记
- Qt学习——布局管理器QLayout类
- Qt学习-->LCD.Sild
- Qt学习笔记3:Qt工程的目录结构
- Qt学习笔记,Qt国际化
- C++/GUI/Qt学习——多线程
- WebKit 学习笔记(6) -- qt4 的应用程序
- Qt: The State Machine Framework 学习
- Qt 学习之路 2