Qt 之实用程序 moc 学习
来源:互联网 发布:js运行 编辑:程序博客网 时间:2024/05/18 10:48
本文关注Qt的工具程序 moc 本身。
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 analysis
moc 将输入文件解析成一个 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 学习小结
- 学习手册之MySQL实用程序
- QT 之 MOC 元对象编译器
- 在vs2010下使用QT之moc的使用
- Qt里的moc
- qt moc problem
- Qt核心剖析: moc
- Qt核心剖析: moc
- Qt核心剖析: moc
- Qt核心剖析: moc
- QT moc限制
- Qt核心剖析: moc
- qt moc-qt4
- Qt核心剖析: moc
- Qt核心剖析: moc
- qt moc笔记
- ioctl 变成了 unlocked_ioctl
- ios中内存的分配与释放
- Mafia's life
- 常用网址
- Android开发之AppWidget应用(二)
- Qt 之实用程序 moc 学习
- 配置本机PC作为MySql Host
- MSagent 学习笔记
- 一键安装linux (附带各种命令,登录欢迎界面,用户登录模块。)
- Torque
- Copy_from_user函数详细分析
- linux内核树的建立
- VMCAI11:SAT-Based Model Checking Without Unrolling
- 博客起航