[再発明] デバッガへの送信ストリーム
Windows 環境では、いわゆる printf デバッグを行うために OutputDebugString API を使用することがよくあります。この API は非常に単純で、使い勝手もそう悪くはありませんが、トレース情報の出力先をデバッガやらファイルやら標準出力やらに切り替えたいときには、FILE 型や std::ostream と交換できないためにやや面倒なこともあります。
そこで誰もが考えるのが、std::streambuf を継承して、OutputDebugString を用いて出力を行うクラスを作る、ないしはそのクラスを用いて std::ostream を継承したクラスを作るということです。そこで、今回は当サイトでも同じことを試みてみました。ただし、ほかでやっているのは std::streambuf::overflow をオーバーライドする実装が多いようですので、当サイトでは std::streambuf::xsputn をオーバーライドすることにしてみました。
デバッガへの送信はデバッグトレースの目的で使うものですから、できるだけ軽量な実装を心がけたのですが、std::ostream 自体が必ずしも軽くないのでほとんど焼け石に水のような気もします。C++ のライブラリでは、ナル終端文字列ではなく、先頭文字へのポインタとサイズで文字列を受け渡しすることが多いので、ナル終端文字列を要求する関数を呼び出す際にはいったん文字列のコピーせざるを得ないのも無視できないオーバーヘッドになります。
とはいえ、1文字ごとに API を呼び出すのはもっと重くなりそうです。本来であれば実測して調べるべきなのでしょうが、この手の API は内部で排他制御が必要になるはずですから、調べるまでもなく軽くはないでしょう。また、sync が呼ばれるまで内部でバッファリングするという方法もあるとは思いますが、デバッグとレースという性質上、過度のバッファリングは有害です。
といったことを考えた結果、今回のような実装にしてみました。使う場合は、win32debugstream.hpp をインクルードするだけで使えます(ライブラリファイルをリンクする必要がありません)ので、扱いは至って簡単です。気が向いた方は試してみてください。バグ報告も歓迎です。
今回は、あまり深く考えずに安易な実装にしています。名前空間も使っていませんし、std::ostream のあらゆる使い方についての検討も行っていません。しかし、実用上はこんなものでも十分ではないかと考えています。
この記事のトラックバックURL:
| 添付 | サイズ |
|---|---|
| win32debugstream.hpp | 2.88 KB |

