Windows C++:如何重定向 stderr 以调用 fprintf?
我将来自 BSD 项目的现有 C++ 代码包装在我们自己的自定义包装器中,并且我希望尽可能少地将其集成到我们的代码中.此代码使用 fprintf
打印到 stderr 以记录/报告错误.
I am wrapping existing C++ code from a BSD project in our own custom wrapper and I want to integrate it to our code with as few changes as possible. This code uses fprintf
to print to stderr in order to log / report errors.
我想将此重定向到同一进程中的其他位置.在 Unix 上,我使用 socketpair
和 thread
完成了此操作:套接字的一端是我发送 stderr(通过调用 dup2
),另一端在一个线程中被监控,然后我可以处理输出.
I want to redirect this to an alternative place within the same process. On Unix I have done this with a socketpair
and a thread
: one end of the socket is where I send stderr (via a call to dup2
) and the other end is monitored in a thread, where I can then process the output.
这在 Windows 上不起作用,因为套接字与文件句柄不同.
This does not work on Windows though because a socket is not the same as a file handle.
我在网上找到的所有文档都展示了如何重定向子进程的输出,这不是我想要的.如何在写入输出时在同一进程中重定向 stderr 以获得某种回调?(在你这么说之前,我已经尝试过 SetStdHandle
,但找不到任何方法来完成这项工作)...
All documents I have found on the web show how to redirect output from a child process, which is not what I want. How can I redirect stderr within the same process getting a callback of some sort when output is written? (and before you say so, I've tried SetStdHandle
but cannot find any way to make this work)...
推荐答案
你可以在 Windows 上使用类似的技术,你只需要为相同的概念使用不同的词.:) 这篇文章:http://msdn.microsoft.com/en-us/library/ms682499.aspx 使用 win32 管道来处理来自另一个进程的 I/O,您只需要对同一进程中的线程执行相同的操作.当然,在您的情况下,从流程中任何地方到 stderr 的所有输出都将重定向到您的使用者.
You can use a similar technique on Windows, you just need to use different words for the same concepts. :) This article: http://msdn.microsoft.com/en-us/library/ms682499.aspx uses a win32 pipe to handle I/O from another process, you just have to do the same thing with threads within the same process. Of course, in your case all output to stderr from anywhere in the process will be redirected to your consumer.
实际上,您可能需要的其他拼图是_fdopen 和 _open_osfhandle.事实上,这是我多年前发布的一些代码的相关示例:
Actually, other pieces of the puzzle you may need are _fdopen and _open_osfhandle. In fact, here's a related example from some code I released years ago:
DWORD CALLBACK DoDebugThread(void *)
{
AllocConsole();
SetConsoleTitle("Copilot Debugger");
// The following is a really disgusting hack to make stdin and stdout attach
// to the newly created console using the MSVC++ libraries. I hope other
// operating systems don't need this kind of kludge.. :)
stdout->_file = _open_osfhandle((long)GetStdHandle(STD_OUTPUT_HANDLE), _O_TEXT);
stdin->_file = _open_osfhandle((long)GetStdHandle(STD_INPUT_HANDLE), _O_TEXT);
debug();
stdout->_file = -1;
stdin->_file = -1;
FreeConsole();
CPU_run();
return 0;
}
在这种情况下,主进程是一个 GUI 进程,它根本不以 stdio 句柄开始.它打开一个控制台,然后将正确的句柄推入 stdout 和 stdin,以便 debug() 函数(它被设计为 stdio 交互函数)可以与新创建的控制台交互.您应该能够打开一些管道并执行相同的操作来重定向 stderr.
In this case, the main process was a GUI process which doesn't start with stdio handles at all. It opens a console, then shoves the right handles into stdout and stdin so the debug() function (which was designed as a stdio interactive function) can interact with the newly created console. You should be able to open some pipes and do the same sort of thing to redirect stderr.
相关文章