Windows API の中には OutputDebugString というものがある。 デバッグ用の文字列をデバッガに通知する API だ。 この API は簡素なので C++ の iostream 系ライブラリに慣れていると使い勝手が悪いと感じるだろう。 ちょっとしたラッパーを書いている人は多いのではないだろうか。
というか、そういう記事を見掛けた。
http://nyaos.org/d/index.cgi?p=%282013.01.08%29#p2
私はちょっと欲を出して他のストリームと同程度のことが出来るようにしたいと思って、もう少し真面目なラッパーを書いてみた。 ヘッダと本体のふたつのファイルから成る。
// dbgstream.hpp #include <windows.h> #include <cstdlib> #include <iostream> template <class Ch,class Tr=std::char_traits<Ch> > class basic_debug_streambuf : public std::basic_streambuf<Ch,Tr> { private: static const int init_size=0x100; int current_size; Ch* buffer; public: basic_debug_streambuf() :current_size(init_size), buffer(NULL) { buffer = static_cast<Ch*>(std::malloc(sizeof(Ch)*init_size)); if(buffer==NULL) throw std::bad_alloc(); this->setp(buffer, &buffer[init_size]); } ~basic_debug_streambuf() { sync(); free(buffer); } protected: std::basic_streambuf<Ch,Tr>* setbuf(Ch* b,int s) { std::free(buffer); this->setp(b, &b[s]); return this; } int overflow(int ch = Tr::eof()) { if(!Tr::eq_int_type(ch, Tr::eof())) { if(this->pptr() >= &buffer[current_size]) { int old_size = current_size; current_size*=2; Ch* old_buffer=buffer; buffer=static_cast<Ch*>(realloc(buffer, sizeof(Ch)*current_size)); if(buffer==NULL) { free(old_buffer); throw std::bad_alloc(); } this->setp(buffer, &buffer[current_size]); this->pbump(old_size); } *(this->pptr()) = Tr::to_char_type(ch); this->pbump(1); return Tr::not_eof(ch); } else { return Tr::eof(); } } int sync(void) { overflow('\0'); OutputDebugString(this->pbase()); this->setp(buffer, &buffer[current_size]); return 0; } }; template <class Ch,class Tr=std::char_traits<Ch> > class basic_debug_stream : public std::basic_ostream<Ch,Tr> { public: basic_debug_stream(void) :std::basic_ostream<Ch,Tr>(new basic_debug_streambuf<Ch,Tr>) { } ~basic_debug_stream(void) { this->flush(); } }; typedef basic_debug_streambuf<char> debug_streambuf; typedef basic_debug_stream<char> debug_stream; extern debug_stream cdbg;
// dbgstream.cpp #include "dbgstream.hpp" debug_stream cdbg;
以下のような要領で使う。 cout を使うときと同じように、数字などもそのまま渡せるし、マニピュレータも使えるので複雑な書式も簡単に書ける。
#include "dbgstream.hpp" using namespace std; int main(void) { cdbg << "1+1=" << 1+1 << endl; cdbg << "100=0x" << hex << 100 << endl; return 0; }
Document ID: c66f234ca642095801bcdc867ce6790e