0

qInstallMessageHandlerカスタムログ機能を登録するために使用します。この関数は、メッセージをフォーマットし (タイム スタンプを追加するなど)、コンソールとログ ファイルに出力します。

私の懸念は、Qt ライブラリ コンポーネント ( QDateTimeQDir、 ... など) が、などQFileを呼び出すことができるかどうかです。qDebug()qWarning()

はいの場合、これは無限再帰につながる可能性があります...

4

1 に答える 1

1

簡単な答えは、メッセージ ハンドラーを再入力しないようにすることです。

// C++11, Qt 5.4+
void myMessageHandler(…) {
  thread_local bool entered = false;
  if (entered) return; // oops
  QScopedValueRollback set{entered, true};
  …
}

// C++11, Qt 4.8+
void myMessageHandler(…) {
  thread_local bool entered = false;
  if (entered) return; // oops
  QScopedValueRollback back{entered};
  entered = true;
  …
}

// C++98, Qt 4
QThreadStorage<bool> entered;
void myMessageHandler(…) {
  if (entered.localData()) return;
  QScopedValueRollback back(entered.localData());
  entered.localData() = true;
  …
}

これは、後世にとって古くてばかげた答えでした:

ロギングが同期している場合にのみ、無限再帰が発生します。ロギングを非同期にするとすぐに、もう問題は発生しません。シグナルを発行した直後に終了し、キュー接続を介したシグナル発行はゼロまたはQMetaCallEvent関連するスレッドのイベント キューにインスタンスを追加するだけです。

非同期ログは、メッセージ ハンドラーでシグナルを発行し、明示的にキューに入れられた接続を介してシグナルに接続されたスロット/ファンクターからのログ書き込みを処理することによって実現されます。おそらく、ロガーを独自のスレッドに常駐させたいと思うでしょう。そのため、これは非常に自然なアプローチであり、うまく機能します。

于 2016-06-24T15:05:26.200 に答える