在win32中重定向stdout不会重定向stdout
Redirecting stdout in win32 does not redirect stdout
我正在尝试重定向stdout,以便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文件句柄和更高层文件描述符/流之间进行映射的适当接口,重定向标准I/O在Windows上更为复杂。
实际上,Windows上有三个不同的I/O层:
- 标准?C I/O流(这些由
printf
、scanf
…使用) - POSIX I/O描述符(这些是
read
、write
…使用的整数) - Win32 API I/O句柄(由
ReadFile
、WriteFile
…使用)
重定向C流
要重定向C流,可以使用freopen
。例如,您可以使用重定向Cstdout
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之上)。也不能保证此重定向将由派生的子代继承。
重定向Windows上的标准I/O
要在Windows上正确重定向I/O,您必须在最低级别(即Win32 API级别)进行重定向,并在更高级别修复链接,如下所示:
- 通过调用
CreateFile
来分配一个新句柄 - 使用
SetStdHandle
将新句柄分配给所需的std I/O设备 - 使用
_open_osfhandle
将该新句柄与相应的C std文件描述符相关联(返回文件描述符编号) - 使用上面解释的
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);
p.S.如果您可以在程序中不进行I/O重定向,那么您可以在命令行中使用一个小批量文件简单地使用控制台的I/O重定向:
@echo off
start "my_gui_app" "path/to/my_gui_app.exe" 1> "path/to/log.txt"
- 如何将stdout重定向到stderr
- 是否可以将子进程的 stdout 重定向到父进程中的另一个文件?
- 尝试在 Windows 上重定向 stdout 和 stderr——_fileno(stdout) 返回 -2
- pybind11将python sys.stdout从print()重定向到c++
- 当使用带有stdin和stdout重定向的双进程管道时,如何避免stdin上的重复输入
- 在win32中重定向stdout不会重定向stdout
- CloseHandle 在 STDOUT 重定向后在 Studio 2010 中引发异常
- 不同的输出在控制台上打印stdout/重定向到文件
- 在Linux上将stdout重定向到文件时,C++程序无法产生输出
- 将Stdout重定向到另一个程序的Stdin
- 在c++中重定向bash stdin和stdout
- 将 CreateProcess() 的 stdout 重定向到管道并在另一个进程 c++ 窗口中读取它
- 重定向PostgreSQL Qt驱动程序stdout/stderr输出
- 在 c++ 中将 FILE * stdout 重定向到字符串
- Android,ADB,将STDOUT重定向到套接字
- 再次将 stdout/stderr 重定向到 UNIX 下的文件
- Qt - 如何将 QProcess' stdout 重定向到 TextEdit
- WIN32:需要帮助与stdout重定向在混合控制台+ GUI应用程序
- 将stdout重定向到编辑控件(Win32).马克II
- 正在将stdout重定向到文件