Динамическая загрузка двух версий libpython

1

У меня есть программа, которая включает в себя как интерпретаторы python2, так и python3. Распространенные библиотеки libpython dlopen() редактируются соответствующими командами, которые предоставляют доступ к интерпретаторам, и каждый интерпретатор поддерживает свое собственное состояние.

Все это работает отлично, если пользователь использует только чистые модули или встроенные модули python. Пытаясь загрузить расширение C (например, termios), затем жалуется "undefined: PyExc_TypeError". Это происходит потому, что расширения C не связаны с libpython. Python upstream не считает, что это проблема .

Чтобы обойти это, я могу изменить вызовы dlopen() в моей программе для библиотек libpython для использования RTLD_GLOBAL. Однако, как только я это делаю, попытка использовать как интерпретаторы python2, так и python3 в том же сеансе программы приводит к тому, что ABRT вызывает вызов Py_Initialize для того, какой второй интерпретатор был вызван вторым. Использование только одного из интерпретаторов прекрасно работает.

Любая идея, как заставить это работать, когда C-расширения не будут связаны с libpython, поэтому требуется использовать RTLD_GLOBAL?

Теги:
dynamic

1 ответ

1
Лучший ответ

Извините, но это не сработает так, как вы этого хотите. Обычно это решение должно связывать каждое расширение с версиями символов libpython; или у вас может быть линкер, совместимый с пространством имен, так что можно сопоставить каждую библиотеку с другим пространством имен, а не с глобальным. К сожалению, ни один из этих вариантов не применяется, поэтому вы, вероятно, придерживаетесь модели с несколькими процессами. Просто вилка и есть одна связь процесса с каждой версией Python. Жесткий бит тогда заключается в том, как разделить любые данные, которые заставили вас требовать от двух разных интерпретаторов Python. Возможно, описание того, какая проблема привела к этому вопросу, может помочь найти лучшее решение?

  • 0
    Программа позволяет использовать интерпретатор python для скриптинга. Ранее он поддерживал только Python2, но недавно получил поддержку Python3. Идея заключалась не в том, чтобы форсировать один или другой параметр, тем более что существуют сценарии, уже написанные с использованием интерфейса Python2. Я думаю, это можно изменить, чтобы отслеживать, был ли один интерфейс уже загружен, а затем предотвратить загрузку другого. Это по-прежнему дает гибкость для сборки с обоими интерпретаторами, но позволяет избежать всей проблемы сбоев. :)
  • 0
    Это казалось бы легким обходным путем, хотя и несколько ограниченным. Более сложный вариант - отделить интерфейс сценариев от языковых привязок, запустить этот интерфейс через подпроцессы, а затем разрешить каждому подпроцессу связываться с любой версией, которая вам нравится. Это будет не так эффективно, и может быть совершенно непрактично в зависимости от вашего текущего интерфейса, но может быть выполнимо, учитывая, что вы можете убрать его сейчас.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню