2011-11-28 6 views
11

He intentado que se ejecute un proyecto mío, pero me he encontrado con problemas. Después de mucha depuración, reduje el problema, pero no tengo idea de cómo proceder.Símbolo indefinido en C++ al cargar una biblioteca compartida de Python

Algunos antecedentes, estoy usando una secuencia de comandos python dentro del código C++. Esto está algo documentado en Python, y logré que funcionara muy bien en mi ejecutable básico. #include y a -lpython2.6 y todo fue grandioso.

Sin embargo, ha surgido una dificultad al ejecutar este script de python desde una biblioteca compartida (.so). Esta biblioteca compartida se "carga" como un "módulo" mediante un sistema de simulación (OpenRAVE). El sistema interactúa con este módulo utilizando un método virtual para "módulos" llamado SendCommand. El módulo inicia un boost :: thread, dando a python su propio hilo y regresa al sistema de simulación. Sin embargo, cuando se inicia la importación de pitón sus módulos y por lo tanto la carga de sus bibliotecas dinámicas se produce un error, supongo que debido al siguiente error:

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

He corrido LDD en mi ejecutable y la biblioteca compartida, no lo hace a algunos a ser una diferencia También corrí nm -D en el archivo anterior, el _Py_ZeroStruct no está definido. Si desean imprimir los comandos, me gustaría proporcionarlos. Cualquier consejo sería muy apreciado, gracias.

Aquí está el error pitón completo:

 
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 

Respuesta

2

La solución fue vincular la biblioteca python2.6 con mi ejecutable también.

Aunque el ejecutable no realizó llamadas de pitón, debe estar vinculado con la biblioteca de python. Supongo que es porque mi biblioteca compartida no pasa los símbolos de la biblioteca de Python al ejecutable. Si alguien pudiera explicar por qué mi ejecutable (que carga mi biblioteca dinámica en tiempo de ejecución, sin vincular) necesita esos símbolos, sería genial.

Para mayor claridad, mi modelo de programa es algo así como: [Mi Ejecutable] - (carga dinámicamente) -> [Mi biblioteca compartida] - (llamadas y conexiones con) -> [Python biblioteca compartida]

0

Compruebe su pitón-cabeceras y el tiempo de ejecución del pitón. Parece que tienes una mezcla de versiones 2.5 y 2.6.

0

hay un ejemplo en openrave que muestra cómo construir objetos compartidos C++ que utilizan impulso pitón sin tener la aplicación saber sobre él:

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

búsqueda de "pitón" en el archivo cmake aquí:

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

la información relevante es:

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

que experimentaron el mismo problema con mi solicitud y lo resolvió sin vincular pitón al ejecutable.

La configuración es la siguiente:

Ejecutable - enlaces -> Biblioteca - dinámicamente cargas -> Plugin - cargas -> Python intérprete

El La solución para evitar ImportErrors era cambiar los parámetros de dlopen, con los que se cargó el complemento en RTLD_GLOBAL.

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

Esto hace que los símbolos disponibles a otras cosas cargados después, es decir, otros plugins o el intérprete de Python.

Sin embargo, puede suceder que se produzcan conflictos de símbolos, ya que un complemento exporta posteriormente los mismos símbolos.

Cuestiones relacionadas