2011-11-28 19 views
11

Próbowałem uruchomić mój projekt, ale mam problem. Po wielu debugowaniu zawęziłem problem, ale nie mam pojęcia, jak postępować.Niezdefiniowany symbol w C++ podczas ładowania współużytkowanej biblioteki Python

Niektóre tła, używam skrypt Pythona wewnątrz kodu C++. Jest to nieco udokumentowane w Pythonie i udało mi się sprawić, by działał bardzo dobrze w moim podstawowym pliku wykonywalnym. #include i -lpython2.6 i wszystko było wspaniałe.

Jednak trudności wystąpiły podczas uruchamiania tego skryptu Pythona z udostępnionej biblioteki (.so). Ta biblioteka współdzielona jest "ładowana" jako "moduł" przez system symulacyjny (OpenRAVE). System współdziała z tym modułem przy użyciu wirtualnej metody dla "modułów" o nazwie SendCommand. Następnie moduł rozpoczyna wątek boost ::, dając pythonowi własny wątek i wraca do systemu symulacji. Jednak, gdy zaczyna pyton importowania jego moduły, a tym samym jego dynamiczne ładowanie bibliotek nie powiedzie, zakładam z powodu następującego błędu:

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

mam uruchomić ldd na moim pliku wykonywalnego i udostępnionej biblioteki, nie robi się niektóre być różnicą. Uruchomiłem również nm-D w powyższym pliku, _Py_ZeroStruct jest rzeczywiście niezdefiniowany. Jeśli chcielibyście wydrukować polecenia, chętnie je dostarczę. Każda rada byłaby bardzo doceniona, dziękuję.

Oto pełna błędów 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 

Odpowiedz

2

Rozwiązaniem było również połączenie biblioteki python2.6 z moim plikiem wykonywalnym.

Nawet jeśli plik wykonywalny nie wykonywał wywołań Pythona, musi być połączony z biblioteką Pythona. Zakładam, że jest tak, ponieważ moja udostępniona biblioteka nie przekazuje symboli biblioteki Pythona do pliku wykonywalnego. Jeśli ktokolwiek mógłby wyjaśnić, dlaczego mój plik wykonywalny (który ładuje moją bibliotekę dynamiczną w czasie wykonywania, bez łączenia) potrzebuje tych symboli, to byłoby wspaniale.

Dla wyjaśnienia, mój model program jest coś takiego: [My wykonywalny] - (dynamicznie ładuje) -> [Moja biblioteka Shared] - (połączenia i powiązania z) -> [Python Biblioteka współdzielona]

0

Sprawdź python-nagłówków i czas pracy Pythona. Wygląda na to, że masz mieszankę wersji 2.5 i 2.6.

0

tam przykład w openrave, który pokazuje, jak zbudować C++ obiektów udostępnionych, które wykorzystują Pythona bez konieczności doładowania aplikacja o tym wiedzieć:

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

wyszukiwania dla „python” w pliku cmake tutaj:

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

dana informacja jest:

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

przeżyłem ten sam problem z mojej aplikacji i rozwiązać go bez powiązania Pythona do pliku wykonywalnego.

Konfiguracja jest następująca:

wykonywalne - linki -> Biblioteka - dynamicznie ładuje -> wtyczki - ładunki -> interpreter Pythona

rozwiązaniem, aby uniknąć ImportErrors było zmienić parametry dlopen, z którym wtyczka została załadowana do RTLD_GLOBAL.

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

To powoduje, że symbole są dostępne dla innych rzeczy załadowanych później, tj. Innych wtyczek lub interpretera pythonów.

Może się jednak zdarzyć, że wystąpią konflikty symboliczne, ponieważ wtyczka później eksportuje te same symbole.