【发布时间】:2018-10-10 21:08:26
【问题描述】:
_open_osfhandle 从 Windows 文件句柄创建 C 文件描述符,_dup 可以更改现有 fd 的底层文件对象。当用于将stdout 重定向到CreatePipe 管道时,ReadFile 不会捕获写入stdout 的输出。
以下代码 sn-p 演示了我正在尝试的核心。
我想创建一个匿名管道,替换 stdout 以便我可以从读取句柄中读取它。
我能够找到的文档表明_open_osfhandle 和_dup2 可以执行此诡计,并且dup2 的Microsoft 文档页面特别呼吁尽可能替换stdout 中的fd。
考虑到这一切,我希望下面的代码会立即从 ReadFile 返回,其中包含 printf 写入的字节,因为之前对 _write 和 fprintf 的调用按预期工作。
HANDLE hread;
HANDLE hwrite;
SECURITY_ATTRIBUTES sa = { sizeof(sa),NULL,TRUE };
CreatePipe(&hread, &hwrite, &sa, 0);
int fd = _open_osfhandle(intptr_t(hwrite), _O_TEXT);
FILE *fp = _fdopen(fd, "w");
setvbuf(fp, NULL, _IONBF, 0);
_dup2(_fileno(fp), _fileno(stdout));
TCHAR buffer[64] = { 0 };
DWORD bytesRead;
//_write(fd, "_write", 6); // works
//fprintf(fp, "fprintf"); // works
printf("printf");
ReadFile(hread, buffer, sizeof(buffer), &bytesRead, NULL);
【问题讨论】:
-
在什么问题?可能
fprintf在内部缓冲区中缓存数据,而不是调用WriteFile。直到您不刷新缓冲区,管道中才会没有数据。在 fprintf 之后调用fflush -
这就是我遇到的问题。直到我发现
setvbuf。最终目标是使用 _dup2 替换标准输出中的 fd。但这仍然行不通。
标签: winapi visual-c++ pipe stdio