Преобразование std::__cxx11::string в 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'
9 ответов
Возможно ли, что вы используете GCC 5?
Если вы получаете ошибки компоновщика о неопределенных ссылках на символы, которые включают типы в пространстве имен std::__cxx11 или теге [abi:cxx11], то это, вероятно, означает, что вы пытаетесь связать вместе объектные файлы, которые были скомпилированы с другими значениями для _GLIBCXX_USE_CXX11_ABI макро. Обычно это происходит при подключении к сторонней библиотеке, которая была скомпилирована с более старой версией GCC. Если сторонняя библиотека не может быть перестроена с новым ABI, вам нужно будет перекомпилировать ваш код со старым ABI.
Источник: GCC 5 Примечания к выпуску /Dual ABI
Определение следующего макроса перед включением любых заголовков стандартной библиотеки должно решить вашу проблему: #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
это тоже хорошо, но вам, вероятно, нужно добавить его ко всем вашим файлам, в то время как опция компилятора сделает это для всех файлов одновременно.
Когда у меня была похожая проблема, это произошло потому, что моя библиотека была собрана с использованием clang++
и это связано с libstdc++.so
по умолчанию в моей системе. В то время как двоичный файл приложения создавался с использованием clang
и связано с -lc++
вариант.
Самый простой способ проверить зависимости - это выполнить ldd libName.so
Чтобы исправить это, вы должны использовать одну и ту же библиотеку в приложении и библиотеке.
Самый простой способ. Сборка библиотеки с использованием
clang++
и скомпилировать приложение, используяclang++
, Без дополнительных ссылок на оба шага. Будет использоваться стандартный stdlib.Сборка библиотеки с
-stdlib=c++
и скомпилировать приложение с-lc++
, В этом случае и библиотека, и приложение будут использоватьlibc++.so
,Сборка библиотеки без дополнительных опций и связывание двоичного файла с
-lstdc++
, В этом случае и библиотека, и приложение будут использоватьlibstdc++.so
,
Ответы здесь в основном сосредоточены на кратком способе его исправить, но если это не поможет, я дам несколько шагов, чтобы проверить, что мне помогло (только для Linux):
- Если при компоновке других библиотек возникают ошибки компоновщика, создайте эти библиотеки с помощью символов отладки (флаг "-g" GCC)
Перечислите символы в библиотеке и наберите символы, на которые жалуется компоновщик (введите команды в командной строке):
nm lib_your_problem_library.a | grep functionNameLinkerComplainsAbout
Если вы получили сигнатуру метода, переходите к следующему шагу, если вы получили
no symbols
вместо этого, скорее всего, вы удалили все символы из библиотеки, и поэтому компоновщик не может найти их при компоновке библиотеки. Перестройте библиотеку без удаления ВСЕХ символов, вы можете удалить отладку (strip -S
вариант) символы, если вам нужно.Используйте demangler C++ для понимания сигнатуры метода, например, этот
- Сравните сигнатуру метода в библиотеке, которую вы только что получили, с сигнатурой, которую вы используете в коде (также проверьте файл заголовка), если они отличаются, используйте правильный заголовок или соответствующую библиотеку или любой другой способ, которым вы теперь знаете, чтобы исправить это
Недавно у меня была аналогичная проблема, когда я пытался подключиться к предварительно созданным двоичным файлам hdf5 версии 1.10.5 на Ubuntu 16.04. Ни одно из предложенных здесь решений не помогло мне, и я использовал g++ версии 9.1. Я обнаружил, что лучшим решением является сборка библиотеки hdf5 из исходников. Не используйте предварительно созданные двоичные файлы, так как они были созданы с использованием gcc 4.9! Вместо этого загрузите архивы исходного кода с веб-сайта hdf для вашего конкретного дистрибутива и создайте библиотеку. Это очень просто.
Вам также потребуется компрессия библиотека ZLIB и 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 Code компилировал файл Bank.cpp. Итак, чтобы решить эту проблему, я просто предложил следующую команду, чтобы успешно скомпилировать файл C++:
g++ Bank.cpp Account.cpp -o Bank
С помощью приведенной выше команды он смог правильно связать файлы C++ заголовка, реализации и основного файла.
OBS: Моя версия g ++: 9.3.0 на Ubuntu 20.04
я сталкивался с подобными проблемами
Оказывается, мой проект использовал gcc 7 и g++ 9 и пытался связать вместе объектные файлы, скомпилированные этими двумя, и все испортилось.
Убедитесь, что вы используете одни и те же версии компилятора во всех проектах.
Я получил это, единственный способ исправить это - обновить все mingw-64 (я сделал это с помощью pacman на msys2 для вашей информации).
Для меня -D_GLIBCXX_USE_CXX11_ABI=0 не помогло.
Это работает после того, как я связался с версией библиотеки C++ вместо gnustl.