我正在包装现有的 C++ 代码 BSD 我们自己的自定义包装器中的项目,我想将其集成到我们的代码中,并进行尽可能少的更改。这段代码使用 fprintf 打印到 标准错误 为了记录/报告错误。

我想将其重定向到同一进程中的另一个位置。在 Unix 我已经这样做了 socketpair 和一个 thread: :套接字的一端是我发送的地方 标准错误 (通过致电 dup2),另一端在线程中进行监视,然后我可以在其中处理输出。

这不适用于 视窗 但因为套接字与文件句柄不同。

我在网上找到的所有文档都显示了如何重定向子进程的输出,这不是我想要的。我怎样才能重定向 标准错误 在同一进程中,在写入输出时获取某种回调?(在你这么说之前,我已经尝试过 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所谓的“操作系统句柄”并不是Win32句柄,而是为了迷惑你而添加的另一层句柄。MSVCRT 尝试模拟 Unix 句柄号,其中 stdin = 0, stdout = 1, stderr = 2 等等。Win32 句柄的编号不同,并且它们的值总是恰好是 4 的倍数。打开管道并正确配置所有手柄将需要弄乱您的手。可能需要使用 MSVCRT 源代码和调试器。

您提到您不想将命名管道用于内部使用;可能值得指出的是,文档 创建管道() 状态, “匿名管道是使用具有唯一名称的命名管道来实现的。因此,您通常可以将匿名管道的句柄传递给需要命名管道句柄的函数。” 因此,我建议您编写一个函数来创建一个类似的管道,并使用正确的异步读取设置。我倾向于使用 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归因
不隶属于 StackOverflow
scroll top