zar*_*ych 5 qt preprocessor qt4 moc
我想使用Q_CLASSINFO宏存储一些类信息.但是我想将它包装在我自己的宏中,例如:
#define DB_TABLE( TABLE ) \
Q_CLASSINFO( "db_table", #TABLE )
#define DB_FIELD( PROPERTY, COLUMN ) \
Q_CLASSINFO( "dbcol_" #PROPERTY, #COLUMN )
class Foo : public QObject
{
Q_OBJECT
DB_TABLE( some_table )
DB_FIELD( clientName, client_name )
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,moc不会扩展宏,因此不会添加Q_CLASSINFO.
我已经尝试用已经预处理的源来提供moc,但它在一些包含的Qt类上有效.
你知道任何解决方法吗?
小智 11
简单的方法就是修改moc预处理器.
搜索线:
// phase 1: get rid of backslash-newlines
input = cleaned(input);
// <- insert your code to modify input variable
// input is a QByteArray object that contents the source code of .h file than moc is processing
// I had created the replaceCustomMacros function, see next line
replaceCustomMacros(input);
...
Run Code Online (Sandbox Code Playgroud)编译新的源代码.moc可执行文件生成到/ bin文件夹(如果使用windows查看c:/bin/moc.exe)
转到Qt bin(C:\ Qt\Qt5.0.1\5.0.1\msvc2010\bin)文件夹并重命名moc可执行文件,例如moc.exe.bak
将新的moc可执行文件复制到Qt bin文件夹.
在当前的应用程序中,您需要创建一个宏,例如:
#ifndef Q_MOC_RUN
#define DB_FIELD( PROPERTY, COLUMN )
#endif
//or in my case
#ifndef Q_MOC_RUN
#define Q_SERVICE_INFO(method, path, type)
#endif
Run Code Online (Sandbox Code Playgroud)最后我告诉你我自己的函数replaceCustomMacros的源代码:
此函数将Q_SERVICE_INFO(方法,路径,类型)宏转换为Q_CLASSINFO("srv:// method","type:path")
void Preprocessor::replaceCustomMacros(QByteArray &source)
{
QString str(QLatin1String(source.data()));
QString param_exp(QLatin1String("([^,\n]+)"));
QByteArray expression("Q_SERVICE_INFO\\s*\\(");
expression
.append(param_exp.toLatin1())
.append(",")
.append(param_exp.toLatin1())
.append("(,")
.append(param_exp.toLatin1())
.append(")?\\)");
QRegExp *reg_ex = new QRegExp(QLatin1String(expression));
int pos = -1, offset = -1, len = str.length();
while ((offset = reg_ex->lastIndexIn(str, pos)) != -1)
{
reg_ex->cap(1);
pos = -(len - offset) - 1;
QString capturedString = reg_ex->capturedTexts().at(0);
QString pattern = capturedString;
pattern.remove(0, pattern.indexOf(QLatin1String("(")) + 1);
pattern.remove(pattern.length() - 1, 1);
QStringList params = pattern.split(QLatin1String(","));
QString method = params.at(0).trimmed();
method = method.mid(1, method.length() - 2);
QString type;
if (params.length() < 3)
{
type.append(QLatin1String("GET"));
}
else
{
type = params.at(2).trimmed();
type = type.mid(1, type.length() - 2);
}
QString path = params.at(1).trimmed();
path = path.mid(1, path.length() - 2);
source.replace(offset, capturedString.length(), QString(QLatin1String("Q_CLASSINFO(\"srv://%1\",\"%2:%3\")")).arg(method, type, path).toLatin1());
}
delete reg_ex;
}
Run Code Online (Sandbox Code Playgroud)
我没有在互联网上找到任何具体的解决方案然后我发布了这个解决方案.
祝好运 :)
除了滚动您自己的 pre-moc 预处理器之外,没有。例如,这就是 MeeGo Touch 所做的事情。既然诺基亚自己都在这么做,我相信也没有其他办法了。
在你的情况下,它只涉及将你自己的声明翻译成 Q_CLASSINFO,所以它应该不会太难。如果您使用 qmake,它也可以添加到构建序列中。