繁体   English   中英

Windows C ++:如何重定向stderr以调用fprintf?

[英]Windows C++: How can I redirect stderr for calls to fprintf?

我在我们自己的自定义包装器中包装来自BSD项目的现有C ++代码,我希望尽可能少地将它集成到我们的代码中。 此代码使用fprintf打印到stderr以记录/报告错误。

我想将其重定向到同一进程中的替代位置。 Unix上我用socketpairthread完成了这个:套接字的一端是我发送stderr的地方 (通过调用dup2 ),另一端是在一个线程中监视,然后我可以处理输出。

这在Windows上不起作用,因为套接字与文件句柄不同。

我在网上找到的所有文档都显示了如何重定向子进程的输出,这不是我想要的。 如何在同一进程中重定向stderr,在写入输出时获得某种回调? (在你这样说之前,我已经尝试过SetStdHandle但找不到任何办法让这项工作)......

您可以在Windows上使用类似的技术,您只需要为相同的概念使用不同的单词。 :)这篇文章: http//msdn.microsoft.com/en-us/library/ms682499.aspx使用win32管道来处理来自另一个进程的I / O,你只需要对同一个线程做同样的事情处理。 当然,在您的情况下,从流程中的任何位置到stderr的所有输出都将重定向到您的消费者。

实际上,您可能需要的其他部分是_fdopen_open_osfhandle 实际上,这是我多年前发布的一些代码的相关示例:

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。

你必须记住,MSVCRT称之为“OS句柄”的不是Win32句柄,而是添加了另一层句柄,只是为了让你感到困惑。 MSVCRT尝试模拟Unix句柄号,其中stdin = 0, stdout = 1, stderr = 2,依此类推。 Win32句柄的编号不同,它们的值总是恰好是4的倍数。打开管道并正确配置所有句柄将需要弄乱手。 可能需要使用MSVCRT源代码和调试器。

您提到您不希望使用命名管道进行内部使用; 可能值得一提的是, CreatePipe()的文档声明, “匿名管道是使用具有唯一名称的命名管道实现的。因此,您通常可以将句柄传递给匿名管道,该句柄需要一个名为句柄的句柄。管。” 因此,我建议您只编写一个函数,使用正确的异步读取设置创建类似的管道。 我倾向于使用GUID作为字符串(使用CoCreateGUID()StringFromIID() )为我提供一个唯一的名称,然后使用正确的重叠I / O设置创建命名管道的服务器和客户端(更多详细信息)关于这个和代码,请访问: http//www.lenholgate.com/blog/2008/02/process-management-using-jobs-on-windows.html )。

有了这个,我连接了一些代码,我必须使用带有I / O完成端口的重叠I / O来读取文件,然后,我只是在到达时得到数据的异步通知...但是,我在那里有相当数量的经过良好测试的库代码,这一切都发生了......

可能可以设置命名管道,然后只对OVERLAPPED结构中的事件执行重叠读取,并检查事件以查看数据是否可用...但我没有任何可用的代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM