簡體   English   中英

加載Python共享庫時C ++中的未定義符號

[英]Undefined Symbol in C++ When Loading a Python Shared Library

我一直試圖讓我的項目運行,但我遇到了麻煩。 經過大量調試后,我已經縮小了問題但不知道如何繼續。

一些背景,我在C ++代碼中使用python腳本。 這在Python上有所記錄,我設法讓它在我的基本可執行文件中運行得很好。 #include和-lpython2.6,一切都很棒。

但是,從共享庫(.so)運行此python腳本時出現了困難。 該共享庫由模擬系統(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確實是未定義的。 如果你們想要打印命令,我很樂意提供它們。 非常感謝任何建議,謝謝。

這是完整的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

我遇到了與我的應用程序相同的問題並解決了它而沒有將 python 鏈接到可執行文件。

設置如下:

可執行文件 - 鏈接 - >庫 - 動態加載 - >插件 - 加載 - > python口譯器

避免ImportErrors的解決方案是更改dlopen的參數,插件加載到RTLD_GLOBAL

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

這使得符號可用於之后加載的其他內容,即其他插件或python解釋器。

但是,可能會發生符號沖突,因為插件稍后會導出相同的符號。

解決方案是將python2.6庫與我的可執行文件鏈接起來。

即使可執行文件沒有進行python調用,它也需要與python庫鏈接。 我假設它是因為我的共享庫沒有將python庫的符號傳遞給可執行文件。 如果有人能解釋為什么我的可執行文件(在運行時加載我的動態庫,沒有鏈接)需要這些符號,那就太好了。

為了澄清,我的程序模型類似於:[我的可執行文件] - (動態加載) - > [我的共享庫] - (調用和鏈接) - > [Python共享庫]

檢查你的python-headers和python的運行時。 看起來你有2.5和2.6版本的混合。

openrave中有一個例子,它展示了如何構建使用boost python的C ++共享對象,而不需要應用程序知道它:

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

在cmake文件中搜索“python”:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM