2011-11-28 27 views
11

私は実行するプロジェクトを取得しようとしていますが、問題が発生しました。多くのデバッグの後、私は問題を絞り込んだが、どのように進めるか分からない。C++で未定義のシンボルがPython共有ライブラリをロードするとき

バックグラウンドによっては、私はC++コードの中でPythonスクリプトを使用しています。これはPython上ではいくらか文書化されていて、基本的な実行可能プログラムでそれをうまく動かすことができました。 #includeと-lpython2.6とすべてが壮大でした。

ただし、このPythonスクリプトを共有ライブラリ(.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は実際には定義されていません。あなたがコマンドのプリントアウトを望むなら、私はそれらを供給することがうれしいでしょう。アドバイスをいただければ幸いです。ありがとうございます。

はここで完全な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 

答えて

2

解決策は、python2.6ライブラリを実行可能ファイルにリンクしていました。

実行可能ファイルはPython呼び出しを行わなかったにもかかわらず、Pythonライブラリにリンクする必要がありました。私は共有ライブラリがPythonライブラリのシンボルを実行可能ファイルに渡さないため、そのコードを仮定します。私の実行可能ファイル(実行時にリンクせずに自分のダイナミックライブラリを読み込む)がそれらのシンボルを必要とする理由を誰かが説明できるなら、それはすばらしいでしょう。

明確にするために、私のプログラムのモデルのようなものです: [マイ実行] - (動的ロード) - > [マイ共有ライブラリ] - (との通話とリンク) - > [Pythonはライブラリを共有]

0

あなたのpython-ヘッダーやPythonのランタイムをチェックしてください。 2.5と2.6のバージョンが混在しているようです。

0

がありますアプリケーションはそれについて知っていることなく、ブーストのpythonを使用してC++共有オブジェクトを構築する方法を示しopenraveの例:

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

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

私は自分のアプリケーションと同じ問題を経験し、実行可能ファイルにのpythonをリンクせずに、それを解決しました。次のように

設定は次のとおりです。

実行可能 - リンク - >ライブラリ - 動的にロード - >プラグイン - 負荷 - > Pythonインタプリタ

ImportErrorsを回避するソリューションは、プラグインがロードされたdlopenのパラメータをRTLD_GLOBALに変更することでした。

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

これにより、他のプラグインやPythonインタプリタなどのシンボルが後で読み込まれるようになります。

プラグインが後で同じシンボルをエクスポートするため、シンボルの衝突が発生する可能性があります。

関連する問題