c++ - 将 stdout/stderr 重定向到 null vs2017 c++

标签 c++ visual-c++ visual-studio-2017

我正在尝试将一个项目从 VS2013 升级到 VS2017。除了一件事,我一切正常——调用 printf 时我遇到了崩溃。崩溃如下:

Unhandled exception at 0x0073910C in exename.exe: An invalid parameter was passed to a function that considers invalid parameters fatal.

exename.exe!_invoke_watson(const wchar_t * expression, const wchar_t * function_name, const wchar_t * file_name, unsigned int line_number, unsigned int reserved) Line 224   C++
exename.exe!_invalid_parameter(const wchar_t * const expression, const wchar_t * const function_name, const wchar_t * const file_name, const unsigned int line_number, const unsigned int reserved) Line 112 C++
exename.exe!_invalid_parameter_noinfo() Line 117 C++
exename.exe!_isatty(int fh) Line 17  C++
exename.exe!__acrt_stdio_begin_temporary_buffering_nolock(_iobuf * public_stream) Line 43    C++
[Inline Frame] exename.exe!__acrt_stdio_temporary_buffering_guard::{ctor}(_iobuf * const stream) Line 399    C++
exename.exe!common_vfprintf::__l2::<lambda>() Line 36    C++
exename.exe!__crt_seh_guarded_call<int>::operator()<void <lambda>(void),int <lambda>(void) &,void <lambda>(void) >(__acrt_lock_stream_and_call::__l2::void <lambda>(void) && setup, common_vfprintf::__l2::int <lambda>(void) & action, __acrt_lock_stream_and_call::__l2::void <lambda>(void) && cleanup) Line 204  C++
exename.exe!__acrt_lock_stream_and_call<int <lambda>(void) >(_iobuf * const stream, common_vfprintf::__l2::int <lambda>(void) && action) Line 256    C++
[Inline Frame] exename.exe!common_vfprintf(const unsigned __int64 options, _iobuf * const stream, const char * const format, __crt_locale_pointers * const locale, char * const arglist) Line 34 C++
exename.exe!__stdio_common_vfprintf(unsigned __int64 options, _iobuf * stream, const char * format, __crt_locale_pointers * locale, char * arglist) Line 58  C++
[Inline Frame] exename.exe!_vfprintf_l(_iobuf * const _Stream, const char * const _Format, __crt_locale_pointers * const) Line 638   C++
exename.exe!printf(const char * const _Format, ...) Line 953 C++

该行看起来像这样:

printf("simple string goes here");

我已将崩溃追踪到这些行:

freopen("/dev/null", "a", stdout);
freopen("/dev/null", "a", stderr);

我可以通过替换以下行来修复它:

freopen("nul", "a", stdout);
freopen("nul", "a", stderr);

我有三个问题要问那些可能比我更了解内部运作的人:

  1. 这在 VS2013 中有效,但在 VS2017 中崩溃(没有更改操作系统)。这是为什么?
  2. 当以 Windows 为目标将所有 stdout/stderr 输出重定向为空时,正确的方法是什么,这样 printf 就不会产生可见的输出?
  3. 是否有安全的跨平台方式来执行此操作?我不一定要寻找插入标准的东西,而是寻找每个主要桌面目标(windows、linux、mac)都可以使用的东西。

编辑

似乎没有可移植的方法来做到这一点,所以我只使用了良好的旧平台特定代码。

    const char* nullStream = "/dev/null";

#if defined(WIN32)
    nullStream = "nul:";
#endif

    // If we fail to redirect either of these streams, we will crash the nex
    // time we try to use them. So we assert to be sure.
    if (!freopen(nullStream, "a", stdout)) assert(false);
    if (!freopen(nullStream, "a", stderr)) assert(false);

最佳答案

这是 Windows 和 Unix 存在不可调和的差异的地方之一,您只需要处理。我会这样做:

#ifdef _WIN32
#define NULL_DEVICE "NUL:"
#else
#define NULL_DEVICE "/dev/null"
#endif

然后

freopen(NULL_DEVICE, "w", stdout);

在 Windows 的情况下,在 NUL 之后放置一个冒号可以防止他们可能在未来的 Windows 版本中决定不希望在每个目录中使用魔法名称。

我不知道为什么 "/dev/null" 在 VS2013 中工作 - 根据我所知道的一切,它不应该。

关于c++ - 将 stdout/stderr 重定向到 null vs2017 c++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45391027/

相关文章:

c++ - 如何确保 C++ 类模板中非静态数据成员的正确初始化

c++ - 在我的项目中包含 C++ 库的最佳实践

visual-studio - 使 Visual Studio 打开工具窗口 float

visual-studio - 如何在安装 Visual Studio 2017 和 2019 后清理硬盘空间?

visual-studio-2017 - Visual Studio 2017 (15.3.1) 一直挂起/卡住

javascript - webextension native 应用程序 c++ hello world

c++ - Win api MessageBox 替代方案,它有一组文本对齐 : center

wpf - 用于开发文本编辑器的 VC (win32) 或 WPF

c++ - 什么时候虚函数表设置为0

.net - 内存泄漏C++/CLI方法