python — Что означает & quot; Символ не найден / ожидается в: плоском пространстве имен & quot; на самом деле значит?

Когда я импортирую созданный мной модуль, я получаю ошибку, связанную с boost-python:

Traceback (most recent call last):
File "<string>", line 1, in <module>
ImportError: dlopen(./myMod.so, 2): Symbol not found: __ZN5boost6python7objects15function_objectERKNS1_11py_functionERKSt4pairIPKNS0_6detail7keywordES9_E
Referenced from: ./myMod.so
Expected in: flat namespace
in ./myMod.so

Что это на самом деле означает? Почему возникла эта ошибка?

18

Решение

Описание

Проблема была вызвана смешением объектов, скомпилированных с libc++ и объект, скомпилированный с libstdc++.

В нашем случае библиотека myMod.so (составлено с libstdc++) необходимость boost-python что составлено с libstdc++ (boost-python-libstdc++ отныне). когда boost-python является boost-python-libstdc++, это будет работать нормально. В противном случае — на компьютере, который его boost-python собрал с libc++ (или другая библиотека c ++), у нее возникнут проблемы с загрузкой и запуском.

В нашем случае это происходит потому, что libc++ разработчики намеренно изменили имя всех своих символов, чтобы вы (и не спасли вас) смешивали код из своей библиотеки и код из другой: myMod.so нужна функция, которая принимает аргумент от типа. В libc++имя этого типа std::__1::pair, Поэтому этот символ не был найден.

Чтобы понять, почему смешивать две версии одного и того же API плохо, рассмотрим следующую ситуацию: Есть две библиотеки: Foo а также Bar, У них обоих есть функция, которая занимает std::string и использует это для чего-то, но они используют другую библиотеку c ++. Когда std::string который был создан Foo будет передан Bar, Bar будет думать, что это экземпляр его библиотеки C ++ std::string и тогда могут случиться плохие вещи (это совершенно разные объекты).

ЗаметкаВ некоторых случаях не было бы проблем с двумя или более различными версиями одного и того же API в совершенно разных частях программы. Будет проблема, если они передадут объекты этого API между ними. Однако проверить это может быть очень сложно, особенно если они передают объект API только как член другого объекта. Кроме того, функция инициализации библиотеки может делать то, что не должно происходить дважды. Другая версия может сделать эти вещи снова.

Как это решить?

  • Вы всегда можете перекомпилировать свои библиотеки и сделать так, чтобы они соответствовали друг другу.

  • Вы можете связать boost-python в вашу библиотеку в качестве статической библиотеки. Затем он будет работать практически на каждом компьютере (даже на том, который не имеет boost-python установлены). Подробнее об этом Вот.

Резюме

myMod.so нужна другая версия boost-pythonтот, который скомпилирован с определенной библиотекой c ++. Таким образом, он не будет работать с любой другой версией.

13

Другие решения

Я сталкиваюсь с той же проблемой.

Expected in: flat namespace

Добавьте флаг компоновщика, чтобы решить проблему

-lboost_python37

измените имя динамической библиотеки на имя, установленное в ОС.

Кстати, моя ОС MacOS High Sierra и я использую brew для установки boost_python3,

2

Вот что я выучил (osx):

Если это должно сработать (то есть работает на другом компьютере), возможно, у вас возникли проблемы clang / gcc. Чтобы отладить это, используйте otool -l в файле .so, который вызывает ошибку, или в подозрительной библиотеке (в моем примере это файл dylib boost-python) и проверьте ее содержимое. Все, что находится в папке / System /, создано с помощью clang и должно быть установлено где-то еще с помощью компилятора gcc. Никогда ничего не удаляйте в папке / System.

1

.so файлы являются динамическими библиотеками (так = общий объект). На винде они называются .dll (динамически подключаемая библиотека). Они содержат скомпилированный код, который содержит функции, доступные для использования с любым исполняемым файлом, который связывает их.

Здесь важно отметить, что эти .so не являются файлами Python. Вероятно, они были скомпилированы из кода C или C ++ и содержат публичные функции, которые можно использовать из кода Python (см. Документацию на Расширение Python с помощью C или C ++).

По твоему делу, ну у тебя коррупционер .so, Попробуйте переустановить уязвимые библиотеки, или Python, или оба.

1

Символ не найден означает, что определение объявленной функции или переменной не найдено. Когда файл заголовка общего объекта компилируется с вашей программой, компоновщик добавляет символы объявленных функций и объектов в вашу скомпилированную программу. Когда ваша программа загружается загрузчиком ОС, символы разрешаются так, что их определение будет загружено. Только в это время, если реализация отсутствует, загрузчик жалуется, что не может найти определение, возможно, из-за сбоя в разрешении фактического пути к библиотеке, или сама библиотека не была скомпилирована с файлом реализации / исходного кода, где определение функции или объекта находится постоянно. Есть хорошая статья на этот счет в журнале Linux http://www.linuxjournal.com/article/6463.

1
По вопросам рекламы [email protected]