Windows には OutputDebugString という API が用意されています。 これはデバッガへ文字列を通知するものです。 Windows の GUI アプリケーションはコンソールに接続されていないのでいわゆるプリントデバッグがやりづらいのですが、この API を介して状況を把握できます。

デバッガがアタッチされていないときのメッセージは単に捨てられるので、リリース版のソフトにそのまま残しておいてもそれほど害にはなりません。 ごく(わず)かに余計な処理をすることになるだけです。

さて、この API は便利なのですが、 C++ を使っているときには不満な部分もあります。 C++ のオブジェクトを表示する方法はしばしばストリームに対するものしか定義しないことがあり、それを API に渡せる文字配列にするには一度 stringstream に出力するなどといった迂遠な方法を取る必要があるからです。

#include <windows.h>
#include <sstream>

class foo {};

std::ostream& operator<<(std::ostream& os, const foo& obj) {
  return os << "#<foo>";
}

int main(void) {
  // ↓ なんだか不格好
  std::ostringstream ss;
  ss << foo();
  OutputDebugString(ss.str().c_str());
}

小さなことではありますが、この不格好さをどうにか出来ないものかと考えて、 OutputDebugString にストリームのインターフェイスを付けるラッパーをライブラリとして整備しました。

https://github.com/SaitoAtsushi/dbgstream

このライブラリを用いれば std::cout に出力するときと同じような操作でデバッグ文字列を出力できます。 上の例で三行を必要としていたコードは cdbg << foo() << std::endl; の一行で済むようになるわけです。

もちろん、各種のマニピュレータも利用できるので、複雑な書式を構築することもできます。

// マニピュレータを使う場合
#include "dbgstream.h"

int main(void) {
  cdbg << "1+1=" << 1+1 << std::endl;
  cdbg << "100=0x" << std::hex << 100 << std::endl;
  return 0;
}

C++ 標準のストリーム系ライブラリには不評の声が大きいのですが、カスタマイズの余地が大きく、上手く使いこなせるならば有用な道具となることもありそうです。

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.