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

Posted

技术标签:

【中文标题】将 std::__cxx11::string 转换为 std::string【英文标题】:Converting std::__cxx11::string to std::string 【发布时间】:2015-10-28 15:19:41 【问题描述】:

我用的是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'

【问题讨论】:

这个错误听起来更像是编译器找不到insertMember()方法。 嗯,它可以和我其他不使用c++11的程序一起找到它 另外我猜你正在使用 gcc。我希望在字符串标头的std 命名空间中的某处有一些typedef __cxx11::basic_string basic_string。你是否也编译包含H5::CompType 的编译单元? “我使用 c++11,但也有一些没有配置的库”。这种情况是有问题的,你不能真的指望东西能正常工作。 gcc.gnu.org/wiki/Cxx11AbiCompatibilityweb.archive.org/web/20170210052503/http://…等等。 我在排除故障后找到了解决这个问题的方法,所以我想分享一下,问题是我使用gcc而不是g++来编译... 【参考方案1】:

您使用的是 GCC 5 吗?

如果您收到有关未定义符号引用的链接器错误,这些符号涉及 std::__cxx11 命名空间或标签 [abi:cxx11] 中的类型,则可能表明您正在尝试将使用不同值编译的目标文件链接在一起对于 _GLIBCXX_USE_CXX11_ABI 宏。当链接到使用旧版本 GCC 编译的第三方库时,通常会发生这种情况。如果第三方库不能用新的 ABI 重建,那么你需要用旧的 ABI 重新编译你的代码。

来源:GCC 5 Release Notes/Dual ABI

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

【讨论】:

我试过这个;现在我在使用 c++11 函数的任何地方都会遇到链接器错误。也许没有办法让它同时使用 c++11 和编译的 hdf5 库。 对我来说,在 Ubuntu 14.04 上,g++ 6.2 默认编译时将此设置为 0,而在 16.04 上,相同的 g++ 版本编译时将其设置为 1。在 14.04 上,将此设置为 1 不会t 似乎实际上做任何事情;生成的目标文件未使用 CXX11 ABI。我怀疑这是系统限制。 我不确定为什么编译器会抛出undefined reference,在寻找解决方案之前,我检查了我在程序中的整个链接,但没有找到任何东西。之后我决定在网上搜索并找到了这个。它就像魅力一样,谢谢:) 感谢无数倍的人!你把我从需要 20 多个小时的调试噩梦中拯救出来!上帝保佑你!【参考方案2】:

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

-D_GLIBCXX_USE_CXX11_ABI=1

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

-D_GLIBCXX_USE_CXX11_ABI=0

定义

#define _GLIBCXX_USE_CXX11_ABI 0/1

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

【讨论】:

编译器标志对我有用。谢谢。我为 gcc 的这个愚蠢的变化浪费了 4 天!【参考方案3】:

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

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

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

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

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

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

【讨论】:

【参考方案4】:

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

如果链接其他库时发生链接器错误,请使用调试符号(“-g”GCC 标志)构建这些库

列出库中的符号并 grep 链接器抱怨的符号(在命令行中输入命令):

nm lib_your_problem_library.a | grep functionNameLinkerComplainsAbout

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

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

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

【讨论】:

【参考方案5】:

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

【讨论】:

【参考方案6】:

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

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

【讨论】:

【参考方案7】:

我最近在尝试链接 Ubuntu 16.04 上 hdf5 版本 1.10.5 的预构建二进制文件时遇到了类似问题。这里建议的解决方案都不适合我,我使用的是 g++ 9.1 版。我发现最好的解决方案是从源代码构建 hdf5 库。不要使用预先构建的二进制文件,因为它们是使用 gcc 4.9 构建的!相反,从 hdf website 为您的特定发行版下载源代码存档并构建库。这很容易。

如果您的系统上还没有压缩库 zlibszip,分别来自 here 和 here。

【讨论】:

【参考方案8】:

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

/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 Code 编译 Bank.cpp 文件的方式产生的。所以,为了解决这个问题,我只提示了以下命令以成功编译 c++ 文件:

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

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

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

【讨论】:

以上是关于将 std::__cxx11::string 转换为 std::string的主要内容,如果未能解决你的问题,请参考以下文章

编辑: std::vector<std::__cxx11::basic_string<char> >' 到 'std::__cxx11::string' aka 'std::_

Travis CI 上的 Boost 中对 `std::__cxx11::basic_string 的未定义引用

undefined reference to `std::__cxx11::basic_string<char,

错误:没有匹配函数调用‘std::__cxx11::basic_string<char>::basic_string(int&)’

错误:没有匹配函数调用‘std::vector<std::__cxx11::basic_string<char> >::push_back(int&)’

[C++][原创]std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)’未定义的引用