尝试在 Windows 上重定向 stdout 和 stderr——_fileno(stdout) 返回 -2



这是我的第一个问题!

我即将将一些精细的工作C++代码从 UNIX 移植到 Windows,它通过管道将 stdout 和 stderr 重定向到自定义 GUI 组件。我需要它来显示来自第三方库的反馈,该库仅将消息输出到我的 GUI 上的 stdout。

根据这个答案 https://stackoverflow.com/a/617158 这应该有效。事实上,链接中的代码在使用 Visual Studio 2017 构建的新命令行应用程序中按预期工作。但是,在我现有的 GUI 应用程序中,对_fileno(stdout)_fileno(stderr)的调用都返回 -2 而不是预期的值 1 和 2,因此什么也没发生。将 1 和 2 硬编码到相关函数也不会使其工作。

所以谁能解释一下

  • 返回值 -2 到底是什么意思?(谷歌搜索了很多 - 没有成功(
  • 如果有可能在 Windows 上为没有控制台的应用程序实现我想要的东西?
  • 如果可能,有哪些相关步骤可以使其正常工作?

供您参考,我收集了到目前为止在Linux和Mac OS上编程的主要经验,因此对于有经验的Windows人员来说,这可能是显而易见的。GUI应用程序基于JUCE框架,所以我使用的是由JUCE工具Projucer创建的自动生成的Visual Studio项目。

与Unix类型的系统不同,在Windows中,控制台应用程序和GUI应用程序是两个不同的东西。GUI应用程序没有stdin,stdout或stderr的概念 - 它们只知道Windows,文本框等。

_fileno的文档说:

如果标准输出

或标准输出未与输出流关联(对于 例如,在没有控制台窗口的 Windows 应用程序中(,文件 返回的描述符为 -2。

因此,如果要使用 stdout 和 stderr,则需要将应用程序构建为控制台应用程序(您仍然可以使用 GUI(。

另一种方法是继续将应用程序构建为 GUI,但通过在应用程序开始时调用 AllocConsole(( 来分配控制台(即您在WinMain()中执行的第一件事(,然后关联 stdout 和 stderr 文件:

if(AllocConsole()){
freopen("CONOUT$", "w", stdout);
freopen("CONOUT$", "w", stderr);
}

我让它与@DodgyCodeException提出的AllocConsole方法一起工作。最后,我现在在我的 GUI 组件的构造函数中调用以下代码来启动控制台并立即隐藏它,以便用户不会被空控制台窗口混淆:

if(AllocConsole())
{ 
freopen ("CONOUT$", "w", stdout); 
freopen ("CONOUT$", "w", stderr); 
ShowWindow (FindWindowA ("ConsoleWindowClass", NULL), false); 
}

这在运行时效果很好,例如,这样在构造相应的 GUI 组件之前不会调用它。此外,这种方法使代码对我来说更容易重用,因为将其包含在进一步的项目中只需要添加源文件,而不是牢记修改构建时设置的需要。

最新更新