Undefined Символ в С++ при загрузке общей библиотеки Python

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

В некоторых случаях я использую python script внутри кода С++. Это несколько документировано на Python, и мне удалось запустить его очень хорошо в моем основном исполняемом файле. #include и -lpython2.6, и все было грандиозным.

Однако возникла трудность при запуске этого python script из общей библиотеки (.so). Эта разделенная библиотека "загружается" как "модуль" с помощью системы моделирования (OpenRAVE). Система взаимодействует с этим модулем, используя виртуальный метод для "модулей", называемых SendCommand. Затем модуль запускает boost:: thread, давая python собственный поток и возвращается в систему моделирования. Однако, когда python начинает импортировать свои модули и, таким образом, загружая свои динамические библиотеки, он терпит неудачу, я предполагаю из-за следующей ошибки:

 ImportError: /usr/lib/python2.6/dist-packages/numpy/core/multiarray.so: undefined symbol: _Py_ZeroStruct 

Я запустил ldd в своем исполняемом файле и в разделяемой библиотеке, там нет какой-то разницы. Я также запускал nm -D в файле выше, _Py_ZeroStruct действительно undefined. Если вы, ребята, хотели бы распечатать команды, я был бы рад предоставить их. Любые советы будут очень признательны, спасибо.

Вот полная ошибка python:

Traceback (most recent call last):
  File "/usr/lib/python2.6/dist-packages/numpy/__init__.py", line 130, in 
    import add_newdocs
  File "/usr/lib/python2.6/dist-packages/numpy/add_newdocs.py", line 9, in 
    from lib import add_newdoc
  File "/usr/lib/python2.6/dist-packages/numpy/lib/__init__.py", line 4, in 
    from type_check import *
  File "/usr/lib/python2.6/dist-packages/numpy/lib/type_check.py", line 8, in 
    import numpy.core.numeric as _nx
  File "/usr/lib/python2.6/dist-packages/numpy/core/__init__.py", line 5, in 
    import multiarray
ImportError: /usr/lib/python2.6/dist-packages/numpy/core/multiarray.so: undefined symbol: _Py_ZeroStruct
Traceback (most recent call last):
  File "/home/constantin/workspace/OpenRAVE/src/grasp_behavior_2.py", line 3, in 
    from openravepy import *
  File "/home/constantin/workspace/rospackages/openrave/lib/python2.6/site-packages/openravepy/__init__.py", line 35, in 
    openravepy_currentversion = loadlatest()
  File "/home/constantin/workspace/rospackages/openrave/lib/python2.6/site-packages/openravepy/__init__.py", line 16, in loadlatest
    return _loadversion('_openravepy_')
  File "/home/constantin/workspace/rospackages/openrave/lib/python2.6/site-packages/openravepy/__init__.py", line 19, in _loadversion
    mainpackage = __import__("openravepy", globals(), locals(), [targetname])
  File "/home/constantin/workspace/rospackages/openrave/lib/python2.6/site-packages/openravepy/_openravepy_/__init__.py", line 29, in 
    from openravepy_int import *
ImportError: numpy.core.multiarray failed to import

Ответ 1

Решение также связывает библиотеку python2.6 с моим исполняемым файлом.

Несмотря на то, что исполняемый файл не выполнял никаких вызовов python, его необходимо было связать с библиотекой python. Я предполагаю, потому что моя общая библиотека не передает символы библиотеки python через исполняемый файл. Если бы кто-нибудь мог объяснить, почему мой исполняемый файл (который загружает мою динамическую библиотеку во время выполнения, без ссылки), нуждается в этих символах, это было бы здорово.

Для уточнения моей модели программы есть что-то вроде: [My Executable] - (динамически загружается) → [Моя общая библиотека] - (вызовы и ссылки с) → [Общая библиотека Python]

Ответ 2

Я столкнулся с той же проблемой с моим приложением и решил ее , не связав python с исполняемым файлом.

Настройка выполняется следующим образом:

Исполняемые --links → library --dynamically-load → plugin --loads → интерпретатор python

Решение избежать ImportErrors состояло в том, чтобы изменить параметры dlopen, с которыми плагин был загружен в RTLD_GLOBAL.

dlopen("plugin.so", RTLD_NOW | RTLD_GLOBAL)

Это делает символы доступными для других вещей, загруженных впоследствии, то есть другие плагины или интерпретатор python.

Однако может случиться, что конфликты символов происходят, потому что плагин позже экспортирует одни и те же символы.

Ответ 3

Проверьте свои заголовки python и время выполнения python. Похоже, у вас есть сочетание версий 2.5 и 2.6.

Ответ 4

есть пример в openrave, который показывает, как создавать общие объекты на С++, которые используют boost python, не зная об этом приложение:

http://openrave.org/en/coreapihtml/orpythonbinding_8cpp-example.html

найдите "python" в файле cmake здесь:

https://openrave.svn.sourceforge.net/svnroot/openrave/trunk/src/cppexamples/CMakeLists.txt

соответствующая информация:

if( Boost_PYTHON_FOUND AND Boost_THREAD_FOUND )
  find_package(PythonLibs)
  if( PYTHONLIBS_FOUND OR PYTHON_LIBRARIES )
    if( PYTHON_EXECUTABLE )
      # get the site-packages directory
      execute_process(
        COMMAND ${PYTHON_EXECUTABLE} -c "from distutils.sysconfig import get_python_lib; print get_python_lib(1)"
        OUTPUT_VARIABLE _python_sitepackage
        RESULT_VARIABLE _python_failed)
      if( ${_python_failed} EQUAL 0 )
        string(REGEX REPLACE "[\r\n]" "" _python_sitepackage "${_python_sitepackage}")
        set(PYTHON_INCLUDE_PATH ${PYTHON_INCLUDE_PATH} ${_python_sitepackage}/numpy/core/include)
      else()
        message(STATUS "failed to get python site-package directory")
      endif()
    endif()

    include_directories(${PYTHON_INCLUDE_PATH} ${OpenRAVE_INCLUDE_DIRS})
    add_library(orpythonbinding SHARED orpythonbinding.cpp)
    target_link_libraries(orpythonbinding ${OpenRAVE_LIBRARIES} ${PYTHON_LIBRARIES} ${Boost_PYTHON_LIBRARY} ${Boost_THREAD_LIBRARY})
    set_target_properties(orpythonbinding PROPERTIES PREFIX "" COMPILE_FLAGS "${OpenRAVE_CXX_FLAGS}")
    if( WIN32 )
      set_target_properties(orpythonbinding PROPERTIES SUFFIX ".pyd")
    endif()
  endif()
endif()