我有一个使用 C++ 库的 Qt/C++ 应用程序。
这个库有一个日志机制,可以将字符串消息写入标准错误。
现在,我希望能够将这些消息重定向到我的 Qt 工具中的面板。 我想避免修改库,因为它被许多其他客户采用。 知道如何在运行时获取这些消息吗?
如果有可能更改它,那么将这些消息传送到应用程序的最佳做法是什么?
最佳答案
这是非常糟糕的图书馆设计。然而……
它如何写入标准错误。如果输出到 std::cerr
,
然后你可以改变streambuf
被 std::cerr
使用,类似于:
std::filebuf logStream;
if ( ~logStream.open( "logfile.txt" ) )
// Error handling...
std::streambuf* originalCErrStream = std::cerr.rdbuf();
std::cerr.rdbuf( &logStream );
// Processing here, with calls to library
std::cerr.rdbuf( originalCErrStream ); // Using RAII would be better.
只是不要忘记恢复原来的streambuf;离开 std::cerr
指向 filebuf
已被销毁不是一个好主意。
如果他们使用 FILE*
, 有一个 freopen
C 中的函数(以及
包含在 C++ 中),你可以使用。
如果他们使用系统级输出(Unix 下的 write
,WriteFile
在 Windows 下),那么你将不得不使用一些系统级代码
改变输出。 (open
在新文件上,close
在 fd
STDERR_FILENO
, 和 dup2
设置 STDERR_FILENO
使用新的
在 Unix 下打开文件。我不确定这是否可能
Windows——可能是 ReOpenFile
的东西或一些组合
CloseHandle
其次是 CreateFile
.)
编辑:
我刚刚注意到您实际上想要输出到 Qt 窗口。这
意味着您可能需要一个字符串,而不是一个文件。如果
图书馆正在使用 std::cerr
, 你可以使用 std::stringbuf
, 代替
一个std::filebuf
;事实上,你可能想要创建你自己的 streambuf,
接听电话 sync
(通常会在每次
<<
在 std::cerr
).如果图书馆使用其他技术之一,
我唯一能想到的就是定期读取文件,看看
如果添加了任何内容。 (我会在 Unix 中使用 read()
,ReadFile()
在 Windows 中,为了确保能够区分
读取零字节,因为自上次以来没有写入任何内容
读,和一个错误条件。 FILE*
和 iostream 函数处理
读取零字节作为文件末尾,并且不会进一步读取。)
关于c++ - 如何从库中读取标准错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9189461/