Link to home
Start Free TrialLog in
Avatar of sean-keys
sean-keys

asked on

Redirecting CLI output in a c++ QT app.

HI Guys,
I'm trying to redirect all stdout to a text box in my QT 4 app.  I found the following code in a forum and other people said it worked.  My problem is that I'm new to c++ and cant figure out the following compiler error message.  Any input would be appriciated.

 error: ‘myRedirector’ was not declared in this scope
freeems_loader.cpp:29: error: no matching function for call to ‘StdRedirector<char, std::char_traits<char> >::StdRedirector(std::ostream&, <unresolved overloaded function type>, QTextBrowser*&)’
freeems_LoaderRedirector.h:29: note: candidates are: StdRedirector<Elem, Tr>::StdRedirector(std::ostream&, void (*)(const Elem*, std::streamsize, void*), void*) [with Elem = char, Tr = std::char_traits<char>]
freeems_LoaderRedirector.h:16: note:                 StdRedirector<char, std::char_traits<char> >::StdRedirector(const StdRedirector<char, std::char_traits<char> >&)
freeems_loader.cpp:33: warning: the address of ‘QTextStream& endl(QTextStream&)’ will always evaluate as ‘true’
make[1]: *** [debug/freeems_loader.o] Error 1
make: *** [debug] Error 2
#ifndef FREEEMS_LOADERREDIRECTOR_H_
#define FREEEMS_LOADERREDIRECTOR_H_


#endif /* FREEEMS_LOADERREDIRECTOR_H_ */

template< class Elem = char, class Tr = std::char_traits< Elem > >
  class StdRedirector : public std::basic_streambuf< Elem, Tr >
  {
      /**
        * Callback Function.
        */
    typedef void (*pfncb) ( const Elem*, std::streamsize _Count, void* pUsrData );

  public:
      /**
        * Constructor.
        * @param a_Stream the stream to redirect
        * @param a_Cb the callback function
        * @param a_pUsrData user data passed to callback
        */
    StdRedirector( std::ostream& a_Stream, pfncb a_Cb, void* a_pUsrData ) :
      m_Stream( a_Stream ),
      m_pCbFunc( a_Cb ),
      m_pUserData( a_pUsrData )
    {
        //redirect stream
      m_pBuf = m_Stream.rdbuf( this );
    };

      /**
        * Destructor.
        * Restores the original stream.
        */
    ~StdRedirector()
    {
      m_Stream.rdbuf( m_pBuf );
    }

      /**
        * Override xsputn and make it forward data to the callback function.
        */
    std::streamsize xsputn( const Elem* _Ptr, std::streamsize _Count )
    {
      m_pCbFunc( _Ptr, _Count, m_pUserData );
      return _Count;
    }

      /**
        * Override overflow and make it forward data to the callback function.
        */
    typename Tr::int_type overflow( typename Tr::int_type v )
    {
      Elem ch = Tr::to_char_type( v );
      m_pCbFunc( &ch, 1, m_pUserData );
      return Tr::not_eof( v );
    }

 protected:
    std::basic_ostream<Elem, Tr>& m_Stream;
    std::streambuf*               m_pBuf;
    pfncb                         m_pCbFunc;
    void*                         m_pUserData;
  };
#########################################################

#include "freeems_LoaderRedirector.h"

a function in my QT GUI class

void FreeEMS_Loader::redirectCLI()
{
	myRedirector = new StdRedirector <>(std::cout,   outCallBack, ui.textOutput);

	std::cout <<"Hello! We are ready" << endl;
}

Open in new window

Avatar of jkr
jkr
Flag of Germany image

Well, the declaration is missing and the call to 'new' also seems to be missing its template argument - did you mean the following?
void FreeEMS_Loader::redirectCLI()
{
	StdRedirector`* myRedirector = new StdRedirector <char>(std::cout,   outCallBack, ui.textOutput);

	std::cout <<"Hello! We are ready" << endl;
}

Open in new window

Ooops, typo, that should be
void FreeEMS_Loader::redirectCLI()
{
	StdRedirector* myRedirector = new StdRedirector <char>(std::cout,   outCallBack, ui.textOutput);

	std::cout <<"Hello! We are ready" << endl;
}

Open in new window

Avatar of sean-keys
sean-keys

ASKER

Now I get a different error, thanks for the fast response.

 missing template arguments before ‘*’ token
freeems_loader.cpp:29: error: ‘myRedirector’ was not declared in this scope
freeems_loader.cpp:29: error: no matching function for call to ‘StdRedirector<char, std::char_traits<char> >::StdRedirector(std::ostream&, <unresolved overloaded function type>, QTextBrowser*&)’
Argh, my bad, not a good idea to mention the template argument and then omitting it again - try
void FreeEMS_Loader::redirectCLI()
{
	StdRedirector<char>* myRedirector = new StdRedirector <char>(std::cout,   outCallBack, ui.textOutput);

	std::cout <<"Hello! We are ready" << endl;
}

Open in new window

Getting closer, I apologize for my ignorance.    

 error: no matching function for call to ‘StdRedirector<char, std::char_traits<char> >::StdRedirector(std::ostream&, <unresolved overloaded function type>, QTextBrowser*&)’
freeems_LoaderRedirector.h:29: note: candidates are: StdRedirector<Elem, Tr>::StdRedirector(std::ostream&, void (*)(const Elem*, std::streamsize, void*), void*) [with Elem = char, Tr = std::char_traits<char>]
freeems_LoaderRedirector.h:16: note:                 StdRedirector<char, std::char_traits<char> >::StdRedirector(const StdRedirector<char, std::char_traits<char> >&)
freeems_loader.cpp:35: warning: the address of ‘QTextStream& endl(QTextStream&)’ will always evaluate as ‘true’
How is 'outCallBack' declared?

void FreeEMS_Loader::outCallBack( const char* ptr, std::streamsize count, void* pTextBox )
{
  (void) count;
  QTextBrowser* p = static_cast< QTextBrowser* >( pTextBox );
  p->append( ptr );
}
ASKER CERTIFIED SOLUTION
Avatar of jkr
jkr
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks!