Converting std::__cxx11::string to std::string
Asked Answered
A

9

92

I use c++11, but also some libraries that are not configured for it, and need some type conversion. In particular I need a way to convert std::__cxx11::string to regular std::string, but googling I can't find a way to do this and putting (string) in front does not work.

If I do not convert I get linker errors like this:

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'
Alderman answered 28/10, 2015 at 15:19 Comment(10)
The error sounds more like the compiler cannot find the insertMember() method.Damiano
Hm, it can find it with other programs I have that do not use c++11Alderman
Actually it seems to be the linker, not the compiler. What does "find" mean, what are those "other programs"?Damiano
Additionally I guess you're using gcc. I would expect that there is some typedef __cxx11::basic_string basic_string somewhere in std namespace of the string header. Do you compile the compilation unit containing H5::CompType as well?Damiano
"find" as in searching for a way to convert on google. "other programs": the one complaining here is the hdf5 library, which I'm not compiling myself (using libraries on shared computers).Alderman
You said "it can find it with other programs I have", but your latest comment does not really fit that phrase. Please clarifyDamiano
"I use c++11, but also some libraries that are not configured for it". This situation is problematic and you cannot really expect stuff to work. gcc.gnu.org/wiki/Cxx11AbiCompatibility web.archive.org/web/20170210052503/http://… and so on.Ehtelehud
@MatthäusBrandl Oh sorry wrong "find", I meant that other programs (which don't include the hdf5 library) don't give the linker error.Alderman
Your hdf5 library was compiled with the old GCC ABI. Either get someone to recompile it or see my answer.Damiano
I found my way to this question after troubleshooting, so I thought I'd share, the problem was that I was using gcc instead of g++ to compile...Adversative
D
129

Is it possible that you are using 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.

Source: GCC 5 Release Notes/Dual ABI

Defining the following macro before including any standard library headers should fix your problem: #define _GLIBCXX_USE_CXX11_ABI 0

Damiano answered 28/10, 2015 at 15:44 Comment(4)
I tried this; now I get linker errors everywhere I use c++11 functions. Maybe there's no way to get this working with both c++11 and the compiled hdf5 library.Alderman
For me, on Ubuntu 14.04, g++ 6.2 compiles by default with this set to 0, while on 16.04, the same g++ version compiles with it set to 1. On 14.04, setting this to 1 doesn't seem to actually do anything; the resulting object file isn't using the CXX11 ABI. I suspect this is a system limitation.Joseph
I wasn't sure why compiler throwing undefined reference and before searching for solution i checked my entire linkage in program and didn't find anything. After that i decided to search on web and found this. It works like charm, thanks :)Schaerbeek
Thanks a quadzillion times man! you saved me from a debugging nightmare that took 20+ hours! God bless you!Jessalyn
J
60

If you can recompile all incompatible libs you use, do it with compiler option

-D_GLIBCXX_USE_CXX11_ABI=1

and then rebuild your project. If you can't do so, add to your project's makefile compiler option

-D_GLIBCXX_USE_CXX11_ABI=0

The define

#define _GLIBCXX_USE_CXX11_ABI 0/1

is also good but you probably need to add it to all your files while compiler option do it for all files at once.

Jelle answered 27/5, 2016 at 8:12 Comment(1)
Compiler flag worked for me. thanks. I wasted 4 days for this stupid change in gcc!Thaw
E
11

When I had similar issue it's happened because my lib was build using clang++, and it's linked to libstdc++.so by default on my system. While app binary was build using clang and linked with -lc++ option.

Easiest way to check dependencies is to perform ldd libName.so

To fix it you should use the same library on in app and library.

  • Easiest way. Build library using clang++ and compile app using clang++. Without extra linking options on both steps. Default stdlib will be used.

  • Build library with -stdlib=c++ and compile app with -lc++. In this case both library and app will use libc++.so.

  • Build library without extra options and link binary to -lstdc++. In this case both library and app will use libstdc++.so.

Electrojet answered 30/7, 2019 at 10:11 Comment(1)
I also had a similar issue where the library for which linking was failing was compiled using a different version of gcc using ldd helped identify the correct version of gcc which I shall be using for new compilationEleven
T
5

Answers here mostly focus on short way to fix it, but if that does not help, I'll give some steps to check, that helped me (Linux only):

  • If the linker errors happen when linking other libraries, build those libs with debug symbols ("-g" GCC flag)
  • List the symbols in the library and grep the symbols that linker complains about (enter the commands in command line):

    nm lib_your_problem_library.a | grep functionNameLinkerComplainsAbout

  • If you got the method signature, proceed to the next step, if you got no symbols instead, mostlikely you stripped off all the symbols from the library and that is why linker can't find them when linking the library. Rebuild the library without stripping ALL the symbols, you can strip debug (strip -S option) symbols if you need.

  • Use a c++ demangler to understand the method signature, for example, this one

  • Compare the method signature in the library that you just got with the one you are using in code (check header file as well), if they are different, use the proper header or the proper library or whatever other way you now know to fix it
Teteak answered 3/7, 2019 at 14:26 Comment(0)
P
0

I got this, the only way I found to fix this was to update all of mingw-64 (I did this using pacman on msys2 for your information).

Passerby answered 28/6, 2017 at 21:18 Comment(0)
E
0

For me -D_GLIBCXX_USE_CXX11_ABI=0 didn't help.

It works after I linked to C++ libs version instead of gnustl.

Eyot answered 24/5, 2018 at 11:9 Comment(0)
I
0

I had a similar issue recently while trying to link with the pre-built binaries of hdf5 version 1.10.5 on Ubuntu 16.04. None of the solutions suggested here worked for me, and I was using g++ version 9.1. I found that the best solution is to build the hdf5 library from source. Do not use the pre-built binaries since these were built using gcc 4.9! Instead, download the source code archives from the hdf website for your particular distribution and build the library. It is very easy.

You will also need the compression libraries zlib and szip from here and here, respectively, if you do not already have them on your system.

Inefficacious answered 18/12, 2019 at 10:17 Comment(0)
A
0

In my case, I was having a similar problem:

/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

After some researches, I realized that the problem was being generated by the way that Visual Studio Code was compiling the Bank.cpp file. So, to solve that, I just prompted the follow command in order to compile the c++ file sucessful:

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

With the command above, It was able to linkage correctly the Header, Implementations and Main c++ files.

OBS: My g++ version: 9.3.0 on Ubuntu 20.04

Ardeb answered 18/10, 2020 at 5:45 Comment(1)
I have used this solution and this one: #33662875. if you are using VSC on ubuntu, change your build command under a file called tasks.json on your work directory. the argument that reads your cpp file "${file}", it only returns 1 file to be compiled. I changed mine to "${fileDirname}/*.cpp" this will compile all cpp under your project. Please let me know i this solution is worth it am also new on VSC environment.Demmy
C
0

I've encountered similar problems

It turns out my project was using gcc 7 and g++ 9 and tried to link together object files compiled by those two and it all messed up.

Make sure you use the same compiler versions in all your project.

Consubstantiate answered 10/4, 2022 at 12:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.