将std :: __ cxx11 :: string转换为std :: string


73

我使用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'

1
该错误听起来更像是编译器找不到该insertMember()方法。
马特乌斯布兰德

1
嗯,它可以在我没有使用的其他程序中找到它c++11
jorgen

1
另外,我猜您正在使用gcc。我希望字符串标头的名称空间中有些typedef __cxx11::basic_string basic_string地方std。您还编译包含的编译单元H5::CompType吗?
马特乌斯布兰德

4
“我使用c ++ 11,但也使用一些未配置的库”。这种情况是有问题的,您不能真正期望工作正常。gcc.gnu.org/wiki/Cxx11AbiCompatibility web.archive.org/web/20170210052503/http://...等。
n。代词

3
故障排除后,我找到了解决该问题的方法,所以我想与您分享,问题是我使用的是gcc而不是g++编译...
Aaron Franke

Answers:


105

您是否可能正在使用GCC 5?

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

来源:GCC 5发行说明/ Dual ABI

包含任何标准库头之前定义以下宏可以解决您的问题:#define _GLIBCXX_USE_CXX11_ABI 0


4
我试过了 现在我在使用c ++ 11函数的任何地方都遇到链接器错误。也许无法同时使用c ++ 11和已编译的hdf5库。
jorgen

1
对我而言,在Ubuntu 14.04上,默认情况下g ++ 6.2编译时设置为0,而在16.04上,相同的g ++版本将其设置为1。在14.04上,将其设置为1似乎并没有执行任何操作。生成的目标文件未使用CXX11 ABI。我怀疑这是系统限制。
Devin Lane

我不确定为什么要抛出编译器undefined reference,在寻找解决方案之前,我检查了程序中的整个链接,却没有找到任何东西。之后,我决定在网上搜索并找到了这个。它像魅力一样工作,谢谢:)
Shravan40 '16

感谢万亿次的男人!您将我从一个耗时20多个小时的恶梦中解救了出来!上帝祝福你!
里卡

54

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

-D_GLIBCXX_USE_CXX11_ABI = 1

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

-D_GLIBCXX_USE_CXX11_ABI = 0

定义

#定义_GLIBCXX_USE_CXX11_ABI 0/1

也不错,但是您可能需要将其添加到所有文件中,而编译器选项同时将其添加到所有文件中。


3
编译器标志为我工作。谢谢。我为gcc的这一愚蠢更改浪费了4天!
Behrouz.M,2016年

6

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

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

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

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

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

  • 无需额外选项即可构建库,并将二进制文件链接到-lstdc++。在这种情况下,库和应用程序都将使用libstdc++.so


3

这里的答案主要集中在解决它的简短方法上,但是如果这样做没有帮助,我将给出一些检查步骤,这对我有帮助(仅适用于Linux):

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

    nm lib_your_problem_library.a | grep functionNameLinkerComplainsAbout

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

  • 使用C ++ Demangler来了解方法签名,例如,这个

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

0

我知道了,找到解决此问题的唯一方法是更新所有mingw-64(我在msys2上使用pacman进行了此操作以获取信息)。


0

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

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


0

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

如果您的系统上还没有压缩库zlibszip,则分别需要从此处此处


0

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

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

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

使用上面的命令,它能够正确链接标题,实现和Main c ++文件。

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.