将 std::__cxx11::string 转换为 std::string

Converting std::__cxx11::string to std::string

我使用c++11,但也有一些没有为它配置的库,需要一些类型转换。特别是我需要一种将 std::__cxx11::string 转换为常规 std::string 的方法,但谷歌搜索我找不到方法,将 (string) 放在前面也不起作用。

如果我不转换,我会收到这样的链接器错误:

undefined reference to `H5::CompType::insertMember(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned long, H5::DataType const&) const'

您可能使用的是 GCC 5 吗?

If you get linker errors about undefined references to symbols that involve types in the std::__cxx11 namespace or the tag [abi:cxx11] then it probably indicates that you are trying to link together object files that were compiled with different values for the _GLIBCXX_USE_CXX11_ABI macro. This commonly happens when linking to a third-party library that was compiled with an older version of GCC. If the third-party library cannot be rebuilt with the new ABI then you will need to recompile your code with the old ABI.

来源:GCC 5 Release Notes/Dual ABI

定义以下宏 before 包括任何标准库头应该可以解决您的问题:#define _GLIBCXX_USE_CXX11_ABI 0

如果您可以重新编译您使用的所有不兼容的库,请使用编译器选项

-D_GLIBCXX_USE_CXX11_ABI=1

然后重建您的项目。如果你不能这样做,请添加到你的项目的 makefile 编译器选项

-D_GLIBCXX_USE_CXX11_ABI=0

定义

#define _GLIBCXX_USE_CXX11_ABI 0/1

也不错,但您可能需要将它添加到所有文件中,而编译器选项会一次对所有文件执行此操作。

我明白了,我发现解决这个问题的唯一方法是更新所有 mingw-64(我在 msys2 上使用 pacman 完成此操作以供您参考)。

对我来说 -D_GLIBCXX_USE_CXX11_ABI=0 没有帮助。

它在我链接到 C++ 库版本而不是 gnustl 后工作。

这里的答案主要集中在解决它的捷径上,但如果这没有帮助,我会给出一些步骤来检查,这对我有帮助(仅 Linux):

  • 如果在链接其他库时发生链接器错误,请使用调试符号(“-g”GCC 标志)构建这些库
  • 列出库中的符号并grep链接器抱怨的符号(在命令行中输入命令):

    nm lib_your_problem_library.a | grep functionNameLinkerComplainsAbout

  • 如果你得到方法签名,继续下一步,如果你得到 no symbols,很可能你从库中剥离了所有符号,这就是为什么链接器不能'链接库时找不到它们。在不删除所有符号的情况下重建库,如果需要,您可以删除调试(strip -S 选项)符号。

  • 使用c++ demangler来理解方法签名,例如,this one

  • 比较您刚刚获得的库中的方法签名与您在代码中使用的方法签名(同时检查头文件),如果它们不同,请使用正确的头文件或正确的库或您使用的任何其他方式现在知道修复它了

当我遇到类似问题时,它的发生是因为我的库是使用 clang++ 构建的,并且在我的系统上默认情况下它被 link 编辑为 libstdc++.so。虽然应用程序二进制文件是使用 clang 构建的,并且 link 使用 -lc++ 选项编辑。

检查依赖关系的最简单方法是执行 ldd libName.so

要修复它,您应该在应用程序和库中使用相同的库。

  • 最简单的方法。使用 clang++ 构建库并使用 clang++ 编译应用程序。两个步骤都没有额外的 linking 选项。将使用默认标准库。

  • 使用 -stdlib=c++ 构建库并使用 -lc++ 编译应用程序。在这种情况下,库和应用程序都将使用 libc++.so

  • 构建没有额外选项的库,link 二进制到 -lstdc++。在这种情况下,库和应用程序都将使用 libstdc++.so.

我最近在 Ubuntu 16.04 上尝试 link 使用 hdf5 版本 1.10.5 的预构建二进制文件时遇到了类似的问题。 None 这里建议的解决方案对我有用,我使用的是 g++ 9.1 版。我发现最好的解决方案是从源代码构建 hdf5 库。不要使用预构建的二进制文件,因为它们是使用 gcc 4.9 构建的!相反,从 hdf website 下载源代码档案用于您的特定发行版并构建库。非常简单。

您还需要压缩库 zlibhere and here 中的 szip,如果您还没有它们在您的系统上。

就我而言,我遇到了类似的问题:

/usr/bin/ld: Bank.cpp:(.text+0x19c): undefined reference to 'Account::SetBank(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)' collect2: error: ld returned 1 exit status

经过一些研究,我意识到问题是由 Visual Studio 代码编译 Bank.cpp 文件的方式产生的。所以,为了解决这个问题,我只是提示执行以下命令才能成功编译 c++ 文件:

g++ Bank.cpp Account.cpp -o Bank

通过上面的命令,它能够正确链接 Header、Implementations 和 Main c++ 文件。

OBS:我的 g++ 版本:Ubuntu 20.04

上的 9.3.0

我遇到过类似的问题

事实证明我的项目使用的是 gcc 7 和 g++ 9,并试图 link 将这两者编译的目标文件放在一起,结果全都搞砸了。

确保在所有项目中使用相同的编译器版本。