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()