C++ WinAPI-如何将程序的所有标准输出和外部DLL重定向到Win32标准输出句柄?

C++ WinAPI-如何将程序的所有标准输出和外部DLL重定向到Win32标准输出句柄?,c++,c,windows,printf,C++,C,Windows,Printf,我希望能够将Windows应用程序的所有标准输出重定向到Win32标准输出句柄,而不是使用控制台句柄 对于上下文,Emacs Win32常见问题解答如下: 显式使用控制台句柄(CON或CON:)而不是stdin和stdout的程序不能用作Emacs的子进程,它们也不能在shell模式下工作[…]Emacs或shell模式中使用的任何shell都无法方便地将此类进程的输入和输出从控制台重定向到输入和输出管道。唯一的解决办法是使用不直接使用控制台的程序的不同实现。 () 我遇到了FAQ描述的问题:当

我希望能够将Windows应用程序的所有标准输出重定向到Win32标准输出句柄,而不是使用控制台句柄

对于上下文,Emacs Win32常见问题解答如下:

显式使用控制台句柄(CON或CON:)而不是stdin和stdout的程序不能用作Emacs的子进程,它们也不能在shell模式下工作[…]Emacs或shell模式中使用的任何shell都无法方便地将此类进程的输入和输出从控制台重定向到输入和输出管道。唯一的解决办法是使用不直接使用控制台的程序的不同实现。 ()

我遇到了FAQ描述的问题:当从Emacs启动时,程序将运行,但在程序退出之前,它的输出都不会显示在Emacs的
shell
窗口中,就好像stdout在运行时被缓冲并且没有刷新一样。如果从
cmd.exe
或ConEmu运行,同一程序将按预期实时输出标准输出

我想要完成的是使程序的所有输出都显示在Emacs shell中,以便在打印后立即跳转到编译器错误位置。我愿意重写程序的源代码来实现这一点。我想知道通过使用“stdin和stdout”而不是“控制台句柄”来实现这一点需要哪些“不同的实现”细节

据我所知:

  • Windows中有多种类型的I/O,包括C运行时(
    printf
    等)和Win32层(
    ReadFile
    等)
  • 我假设“stdin和stdout”指的是
    STD\u输入\u句柄
    STD\u输出\u句柄
    ,可以通过
    SetStdHandle()
    修改
  • 由程序加载的外部DLL将继承C运行时
    stdin
    stdout
    管道,但这发生在程序初始化时,在调用对
    SetStdHandle()
    的任何调用之前,因此您必须执行其他操作来重定向其输出
  • 我尝试使用以下代码:

    #包括
    #包括
    int main()
    {
    HANDLE hStdout=CreateFile(L“CONOUT$”,GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE,
    NULL,打开\存在,文件\属性\正常,NULL);
    HANDLE hStdin=CreateFile(L“CONIN$”,GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE,
    NULL,打开\存在,文件\属性\正常,NULL);
    设置TDHandle(标准输出句柄,hStdout);
    设置TDHandle(标准错误句柄,hStdout);
    设置TDHandle(标准输入句柄,hStdin);
    
    std::cout我使用了上面提供的代码示例,然后调用
    setvbuf(stdout,NULL,_IONBF,4096)
    来设置非缓冲输出并获得所需的结果。

    不是“好像stdout被缓冲”,当isatty()返回0时,它被缓冲。改为写入stderr或setvbuf()或显式fflush()。