これを作る簡単な方法は、moc プリプロセッサを変更することです。
- Qt ソース コードをqtbase/src/tools/mocに移動します(例: (C:\Qt\Qt5.0.1\5.0.1\Src\qtbase\src\tools\moc))。
- moc プロジェクトの新しいコピーを作成します。例: moc_modified
- moc プロジェクトのコピーを QtCreator で開きます (moc.pro ファイル)
- preprocessor.cpp ファイルを開き、Symbols Preprocessor::preprocessed(const QByteArray &filename, QIODevice *file)関数に移動します。
次の行を検索します。
// 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);
...
新しいソース コードをコンパイルします。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
最後に、関数 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;
}
インターネットで特定の解決策が見つからなかったので、この解決策を投稿しました。
幸運を :)