C ++程序使用<filesystem>库在Windows上没有任何反应

5

我正在尝试在Windows上运行一个使用<filesystem>库的程序。我正在使用MSYS2(64位)的g++编译器。

#include <iostream>
#include <filesystem>

int main()
{
    std::cout << "Hello World\n";
    std::cout << "Current path is " << std::filesystem::current_path() << '\n';
}

我正在使用以下技术构建它:

g++ -std=c++17 -Wall -Werror -Wextra main.cpp -lstdc++fs

编译器没有控制台输出。它默默生成一个a.exe。运行a.exe后什么都不会发生,没有输出和错误信息。在运行程序后,$?(包含程序返回代码)的值为127

g++ -v命令会打印:

Using built-in specs.
COLLECT_GCC=C:\msys64\mingw64\bin\g++.exe
COLLECT_LTO_WRAPPER=C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.1.0/lto-wrapper.exe
Target: x86_64-w64-mingw32
Configured with: ../gcc-9.1.0/configure --prefix=/mingw64 --with-local-prefix=/mingw64/local --build=x86_64-w64-mingw32 --host=x86_64-w64-mingw32 --target=x86_64-w64-mingw32 --with-native-system-header-dir=/mingw64/x86_64-w64-mingw32/include --libexecdir=/mingw64/lib --enable-bootstrap --with-arch=x86-64 --with-tune=generic --enable-languages=c,lto,c++,fortran,ada,objc,obj-c++ --enable-shared --enable-static --enable-libatomic --enable-threads=posix --enable-graphite --enable-fully-dynamic-string --enable-libstdcxx-filesystem-ts=yes --enable-libstdcxx-time=yes --disable-libstdcxx-pch --disable-libstdcxx-debug --disable-isl-version-check --enable-lto --enable-libgomp --disable-multilib --enable-checking=release --disable-rpath --disable-win32-registry --disable-nls --disable-werror --disable-symvers --enable-plugin --with-libiconv --with-system-zlib --with-gmp=/mingw64 --with-mpfr=/mingw64 --with-mpc=/mingw64 --with-isl=/mingw64 --with-pkgversion='Rev3, Built by MSYS2 project' --with-bugurl=https://sourceforge.net/projects/msys2 --with-gnu-as --with-gnu-ld
Thread model: posix
gcc version 9.1.0 (Rev3, Built by MSYS2 project)

可能出了什么问题?

如果我注释掉带有 std::filesystem::current_path() 的行,则可以获得 Hello World 输出并且 $?0,这说明编译器正常工作。


1
尝试添加std :: cout << std :: endl; 也许数据没有刷新到标准输出。 - George
1
非零的退出代码表示程序运行失败。也许您应该确保运行时库可用。 - user7860670
1
你的代码本身是正确的,当我在Linux上编译并运行它时,输出与我预期的一样(它打印出“hello world”,然后是当前路径)。这意味着程序没有加载正确的库,但这就是我所知道的。 - Alecto Irene Perez
1
current_path 可能会抛出异常。请参见此处:https://en.cppreference.com/w/cpp/filesystem/current_path - Michael Mahn
3
看起来你的程序正在尝试加载一些dll时出了问题。 https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/596a1078-e883-4972-9bbc-49e60bebca550xC0000139STATUS_ENTRYPOINT_NOT_FOUND{找不到入口点} 无法在动态链接库%hs中找到%hs过程的入口点。我建议查看Windows应用程序日志中的事件查看器,以了解哪些dll和入口点导致了该问题。 - George
显示剩余6条评论
1个回答

9

感谢评论区的读者提供的想法,最终帮我找到了解决办法。

简述

如果你安装了各种基于MinGW的工具集(例如 Cygwin, MinGW, MSYS, Git Bash),请使用相应工具集附带的shell。只需小心地将mingw*/bin路径添加到PATH中,而不是更改默认的PATH设置。如果您想在MSYS shell中方便地使用上下文菜单快捷方式,请点击此处


一个关于百万个MinGW的故事

问题出现在我奇怪的本地设置上。随着时间的推移,我在电脑上积累了各种版本的 MinGW 工具,它们散布在各个角落。如果我需要某个实用程序,比如diff,我会 google 搜索并从某个地方下载(通常是从 sourceforge),将其安装到某个位置并将bin文件夹添加到我的 PATH中。这种策略对于大多数情况都有效。

我安装过的工具集包括但不限于:

  • MinGW (32 位和 64 位)
  • Cygwin
  • MSYS
  • Git(+ Git Bash)

最近我一直在使用Git Bash来做所有的事情。但最近我想获取最新的g++编译器等工具,发现MSYS2有一个软件包管理器(pacman)和更新的软件包,所以我安装了它,并将其添加到PATH中,然后使用Git Bash

然而,每个工具集都有自己的shell,都有自己的MinGW副本和PATH设置。所以我让我的Git Bash使用MSYS2g++,但从Git Bash执行的应用程序仍然使用Git BashMinGW副本中的DLL。虽然我不能确定,但很可能这就是问题所在。

为了找出问题,我在Git Bash中使用了以下命令:

# because of my PATH adjustment, I got the right g++
$ which g++
/c/msys64/mingw64/bin/g++

# my program uses DLLs from /mingw64, though
$ ldd a.exe
        ntdll.dll => /c/Windows/SYSTEM32/ntdll.dll (0x77060000)
        kernel32.dll => /c/Windows/system32/kernel32.dll (0x76e40000)
        KERNELBASE.dll => /c/Windows/system32/KERNELBASE.dll (0x7fefcc00000)
        msvcrt.dll => /c/Windows/system32/msvcrt.dll (0x7fefcf70000)
        libgcc_s_seh-1.dll => /mingw64/bin/libgcc_s_seh-1.dll (0x61440000)
        libwinpthread-1.dll => /mingw64/bin/libwinpthread-1.dll (0x64940000)
        libstdc++-6.dll => /mingw64/bin/libstdc++-6.dll (0x6fc40000)
        USER32.dll => /c/Windows/system32/USER32.dll (0x76f60000)
        GDI32.dll => /c/Windows/system32/GDI32.dll (0x7fefddb0000)
        LPK.dll => /c/Windows/system32/LPK.dll (0x7fefd540000)
        USP10.dll => /c/Windows/system32/USP10.dll (0x7fefdbe0000)

# with cygpath I can find out that this is actually the Git Bash's installation
$ cygpath -w /mingw64
C:\Program Files\Git\mingw64

MSYS2自带了它自己的shell,它可以正确地设置PATH以使应用程序正常工作。在MSYS2 shell中:

$ ./a.exe
Hello World
Current path is "E:\\temporary\\2019_07_25-gpp_filesystem_test"

如果有人不幸遇到类似情况,希望更轻松地在各个文件夹中使用MSYS2 shell,则可以查看此存储库,其中包含一个reg脚本,设置方便的上下文菜单快捷方式用于MSYS2 shell: https://github.com/njzhangyifei/msys2-mingw-shortcut-menus


2
感谢您发布这个答案!当有人遇到奇怪的问题时,这确实有助于解决问题。 - Alecto Irene Perez
2
你让我开心极了! - slaadvak
现在,你知道在Eclipse中轻松处理所有这些的简单方法吗?我的意思是一种切换所有这些gcc的方式,强制Eclipse使用其中一个,而不必经常使用PATH环境变量进行操作。 - slaadvak
如果你在谈论在Eclipse中进行C++开发,那么它自带自己的工具集吗?我会使用默认设置(并通过Eclipse编译)。 - Neonit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接