Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/148.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Windows C++;:如何将调用的stderr重定向到fprintf?_C++_Windows_Redirect - Fatal编程技术网

C++ Windows C++;:如何将调用的stderr重定向到fprintf?

C++ Windows C++;:如何将调用的stderr重定向到fprintf?,c++,windows,redirect,C++,Windows,Redirect,我在我们自己的自定义包装器中,从一个强> BSD 项目中包装现有C++代码,我想尽可能少地将它集成到代码中。此代码使用fprintf打印到stderr以记录/报告错误 我想把它重定向到同一流程中的另一个地方。在Unix上,我使用socketpair和thread:套接字的一端是我发送stderr(通过调用dup2)的地方,另一端在线程中进行监控,然后我可以在线程中处理输出 但这在Windows上不起作用,因为套接字与文件句柄不同 我在web上找到的所有文档都显示了如何重定向子进程的输出,这不是我

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

我想把它重定向到同一流程中的另一个地方。在Unix上,我使用
socketpair
thread
:套接字的一端是我发送stderr(通过调用
dup2
)的地方,另一端在线程中进行监控,然后我可以在线程中处理输出

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


我在web上找到的所有文档都显示了如何重定向子进程的输出,这不是我想要的。写入输出时,如何在同一进程内重定向stderr,以获得某种回调?(在你这么说之前,我已经试过
SetStdHandle
,但找不到任何方法来实现这一点)

你可以在Windows上使用类似的技术,只需对相同的概念使用不同的词即可。:)本文:使用win32管道处理来自另一个进程的I/O,您只需对同一进程中的线程执行相同的操作。当然,在您的情况下,从过程中的任何位置到stderr的所有输出都将重定向到您的使用者

实际上,你可能需要的其他拼图是和。事实上,这里有一个我几年前发布的相关示例:

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所称的“操作系统句柄”不是Win32句柄,而是添加的另一层句柄,只是为了让您感到困惑。MSVCRT尝试模拟Unix句柄编号,其中
stdin
=0、
stdout
=1、
stderr
=2等等。Win32句柄的编号不同,它们的值总是正好是4的倍数。打开管道并正确配置所有手柄需要将手弄脏。使用MSVCRT源代码和调试器可能是一项要求。

您提到您不希望将命名管道用于内部使用;可能值得一提的是,针对各州的文档“匿名管道是使用具有唯一名称的命名管道实现的。因此,您通常可以将匿名管道的句柄传递给需要命名管道句柄的函数。”,我建议您编写一个函数,创建一个具有正确异步读取设置的类似管道。我倾向于使用GUID作为字符串(使用
CoCreateGUID()
StringFromIID()
生成)来给我一个唯一的名称,然后使用重叠I/O的正确设置创建命名管道的服务器端和客户端(有关这方面的更多详细信息和代码,请参见此处:)

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

可能可以设置命名管道,然后在
overlapped
结构中对事件执行重叠读取,然后检查事件以查看数据是否可用。。。但是我没有任何代码可以实现这一点