Windows API の中には OutputDebugString というものがある。 デバッグ用の文字列をデバッガに通知する API だ。 この API は簡素なので C++ の iostream 系ライブラリに慣れていると使い勝手が悪いと感じるだろう。 ちょっとしたラッパーを書いている人は多いのではないだろうか。
というか、そういう記事を見掛けた。
MHI 5.0 (2013.01.08) OutputDebugString を何回も書くのがうざい
私はちょっと欲を出して他のストリームと同程度のことが出来るようにしたいと思って、もう少し真面目なラッパーを書いてみた。 ヘッダと本体のふたつのファイルから成る。
// 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
0 件のコメント:
コメントを投稿