Преобразование 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.

Другие вопросы по тегам