stdout/stderr を非常に簡単にリダイレクトできます: std::basic_streambuf から派生したクラスを作成し、xsputn() と overflow() をオーバーロードします。次に、たとえば std::cerr.rdbuf( instanceOfYourRedirectClass ) を使用して、すべての stderr 出力をコールバック関数にリダイレクトします。あなたが供給します。
これは私が使用するものの簡略化されたバージョンです。必要に応じて、行末文字などの処理をいじる追加のロジックを追加する必要がある場合があります。
template< class Elem = char, class Tr = std::char_traits<Elem> >
class Redirector : public std::basic_streambuf<Elem, Tr>
{
typedef void (*pfncb) ( const Elem*, std::streamsize );
public:
Redirector( std::ostream& a_Stream, pfncb a_Cb ) :
m_Stream( a_Stream ),
m_pCbFunc( a_Cb ),
{
//redirect stream
m_pBuf = m_Stream.rdbuf( this );
};
~Redirector()
{
//restore stream
m_Stream.rdbuf( m_pBuf );
}
std::streamsize xsputn( const Elem* _Ptr, std::streamsize _Count )
{
m_pCbFunc( _Ptr, _Count );
return _Count;
}
typename Tr::int_type overflow( typename Tr::int_type v )
{
Elem ch = Tr::to_char_type( v );
m_pCbFunc( &ch, 1 );
return Tr::not_eof( v );
}
protected:
std::basic_ostream<Elem, Tr>& m_Stream;
std::streambuf* m_pBuf;
pfncb m_pCbFunc;
};
使用法:
void outcallback( const char *ptr, std::streamsize count )
{
if( *ptr != gc_cEOL ) //ignore eof
OutputDebugString( ptr );
}
Redirector<> redirect( std::cout, mycallback );