gpt4 book ai didi

c++ - 在 win32 中重定向 stdout 不会重定向 stdout

转载 作者:太空宇宙 更新时间:2023-11-04 00:57:33 27 4
gpt4 key购买 nike

我正在尝试重定向标准输出,以便 Windows 应用程序中的 printf 将转到我选择的文件。

我这样做:

outFile = fopen("log.txt", "w");
*stdout = *outFile;
setvbuf(stdout, NULL, _IONBF, 0);

但 printf 仍然写入控制台(或在基于 GUI 的 win32 应用程序上无处写入)

我可以通过这样做来重定向“std::cout”:

outFileStr = std::ofstream(outFile);         
std::cout.rdbuf(outFileStr.rdbuf());

但是 printf 似乎在做自己的事情。不幸的是,我需要重定向 printf,因为我正在尝试将 python 集成到 C++ 框架中,而这似乎依赖于 printf 而不是 std::cout。

std::cout' 似乎被重定向但不是 printf。

最佳答案

由于缺少在任意 Win32 文件句柄和更高层文件描述符/流之间映射的适当接口(interface),重定向标准 I/O 在 Windows 上涉及更多。

Windows 上实际上存在三个不同的 I/O 层:

  1. 标准? C I/O 流(这些由 printfscanf 等使用)
  2. POSIX I/O 描述符(这些是readwrite 等使用的整数)
  3. Win32 API I/O 句柄(由 ReadFileWriteFile 等使用)

重定向 C 流

要重定向 C 流,您可以使用 freopen .例如,您可以重定向 C stdout 使用:

freopen("log.txt", "w", stdout);

此重定向通常不会重定向由 POSIX 或 Win32 API 完成的 I/O(它们仍会读/写附加的控制台,如果有的话)。另外,这个重定向不会被子进程继承。 (在 POSIX 兼容/非 Windows 系统上,通常 POSIX API 也是系统 API,而 C API 是在 POSIX API 之上实现的。在这些情况下,freopen 就足够了.)

重定向 POSIX I/O 描述符

要在 POSIX API 级别重定向 I/O,您可以使用 dup2 .例如,您可以重新分配文件描述符 STDOUT_FILENO 以重定向 stdout,类似于:

int fd = open("log.txt", O_WRONLY);
dup2(fd, STDOUT_FILENO);
close(fd);

不幸的是,在 Windows 上,即使在 POSIX API 级别重定向也不能保证在 C 和 Win32 API 级别重定向。这是否有效取决于在 C 库的实现中投入的努力以在 POSIX 文件描述符和 Win32 文件句柄之间进行映射(假设您正在使用的 C 运行时库首先将其 I/O 分层放置在 POSIX 之上) .也不能保证这种重定向会被派生的 child 继承。

在 Windows 上重定向标准 I/O!

要在 Windows 上正确重定向 I/O,您必须在最低级别(即 Win32 API 级别)重定向,并修复更高级别的链接,如下所示:

  1. 通过调用 CreateFile 分配一个新句柄.
  2. 使用 SetStdHandle 将新句柄分配给所需的标准 I/O 设备.
  3. 使用_open_osfhandle 将该新句柄与相应的C std 文件描述符相关联| (返回文件描述符编号)。
  4. 使用上面解释的 dup2 技术重定向返回的文件描述符。

这里是重定向 stdout 的示例片段:

HANDLE new_stdout = CreateFileA("log.txt", ...);
SetStdHandle(STD_OUTPUT_HANDLE, new_stdout);
int fd = _open_osfhandle(new_stdout, O_WRONLY|O_TEXT);
dup2(fd, STDOUT_FILENO);
close(fd);

附言如果您可以在程序内部不使用 I/O 重定向,那么您可以使用一个小的批处理文件在命令行中简单地使用控制台的 I/O 重定向:

@echo off
start "my_gui_app" "path/to/my_gui_app.exe" 1> "path/to/log.txt"

关于c++ - 在 win32 中重定向 stdout 不会重定向 stdout,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54094127/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com