无法通过stdout写入Windows管道

时间:2018-10-10 21:08:27

标签: winapi visual-c++ pipe stdio

#display a welcome message print("Welcome to the Future Value Calculator") print() choice = "y" while choice.lower() == "y": monthly_invest = int(input("Enter monthly investment:\t")) yearly_interest_rate = float(input("Enter yearly interest rate:\t")) years = int(input("Enter number of years:\t\t")) #convert yearly values to monthly values monthly_interest_rate = yearly_interest_rate / 12 / 100 months = years * 12 future_value = 0 future_value += monthly_invest monthly_amount = future_value * monthly_interest_rate future_value += monthly_amount print() #display the result for i in range(years): print("Year = " + str(i+1) + "\t" + "Future value: " + str(round(future_value))) #see if the user wants to continue print() continue_runs = (input("Continue (y/n)? ")) print("Bye!") 从Windows文件句柄创建一个C文件描述符,_open_osfhandle可以更改现有fd的基础文件对象。用于将_dup重定向到stdout管道时,CreatePipe不会捕获写入ReadFile的输出。

以下代码片段演示了我正在尝试的核心。 我想创建一个匿名管道,替换stdout,以便可以从读取句柄中读取它。

我已经找到的文档表明stdout_open_osfhandle可以执行此技巧,而dup2的Microsoft文档页面专门呼吁尽可能替换stdout中的fd

鉴于所有这些,我希望以下代码能立即从ReadFile返回,其中printf写入的字节是对_dup2_write的先前调用按预期方式工作。

fprintf

1 个答案:

答案 0 :(得分:1)

调查终于取得了成果。 _fdopen打开的文件流默认情况下会进行缓冲,以防止实际将任何内容写入基础OS管道句柄。 setvbuf可用于关闭此功能,以便立即进行写操作。

执行dup2重置绑定到stdout的文件描述符的基础文件将重置缓冲,因此以下代码可以正常工作。对_fdopen的调用会在不需要时删除,并在stdout上执行`setvbuf'。

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);
_dup2(fd, _fileno(stdout));
setvbuf(stdout, NULL, _IONBF, 0);
TCHAR buffer[64] = { 0 };
DWORD bytesRead;
printf("printf");
ReadFile(hread, buffer, sizeof(buffer), &bytesRead, NULL);