I have a Qt/C++ acpplication which is using a C++ library.
This library has a log mechanism that writes string messages to standard error.
Now, I would like to be able to redirect those messages toward a panel in my Qt tool. I would like to avoid modifying the library because is adopted by many other clients. Any idea how to get at runtime these messages?
Having instead the possibility of changing it what could be a good practise for carrying those messages up to the application?
That's very poor library design. However...
How does it write to standard error. If it is outputing to
std::cerr
, then you can change thestreambuf
used bystd::cerr
, something like:Just don't forget to restore the original streambuf; leaving
std::cerr
pointing to afilebuf
which has been destructed is not a good idea.If they're using
FILE*
, there's anfreopen
function in C (and by inclusion in C++) that you can use.If they're using system level output (
write
under Unix,WriteFile
under Windows), then you're going to have to use some system level code to change the output. (open
on the new file,close
on fdSTDERR_FILENO
, anddup2
to setSTDERR_FILENO
to use the newly opened file under Unix. I'm not sure it's possible under Windows—maybe something withReOpenFile
or some combination ofCloseHandle
followed byCreateFile
.)EDIT:
I just noticed that you actually want to output to a Qt window. This means that you probably need a string, rather than a file. If the library is using
std::cerr
, you can use astd::stringbuf
, instead of astd::filebuf
; you may, in fact, want to create your own streambuf, to pick up calls tosync
(which will normally be called after each<<
onstd::cerr
). If the library uses one of the other techniques, the only thing I can think of is to periodically read the file, to see if anything has been added. (I would useread()
in Unix,ReadFile()
in Windows for this, in order to be sure of being able to distinguish a read of zero bytes, due to nothing having been written since the last read, and an error condition.FILE*
and iostream functions treat a read of zero bytes as end of file, and will not read further.)Here I found a complete implemenation of what i needed...
Thanks everybody for the help! :)
Will loading a DLL dynamically reconcile its stderr to a main application? If so, then how...?
write to stderr is actually a syscall:
you can redirect file descriptor number 2 to anything (file, pipe, socket):
in your situation, you will need a pipe.
then, everything write to stderr can be obtained by reading pipe[0]:
If they're using calls to
std::cerr
, you can redirect this to astd::ostringstream
.You can capture the output using:
std::cout
will be unaffected:So you can then test your capture is working:
Or just add the contents of
os.str()
to your Qt Window.Demonstration at ideone.