0

Python以外のC++アプリケーション用のC++「pythonプラグイン」を作成しました。
ある時点で、.so であるこのプラグインは、python インタープリターを初期化し、python コンソールを開きます。
便宜上、「readline」モジュールがインポートされ、次のエラーが発生します。

ImportError: /usr/lib/python2.7/lib-dynload/readline.so: 未定義のシンボル: PyOS_InputHook

リンク コマンド (cmake で生成) は次のようになります。

/usr/bin/c++ -fPIC -Wall -Wextra -O3 -DNDEBUG -Xlinker -export-dynamic -Wl,-fwhole-program /usr/lib/libpython2.7.a -shared -Wl,-soname,libMyplugin.so -o libMyplugin.so [ソース] [qt ライブラリ] -lGLU -lGL -lX11 -lXext -lc -lc -lpython2.7 -Wl,-rpath,/src:/usr/local/Trolltech/Qt-4.8.4/ライブラリ:

nm libMyplugin.so次のpython関連のシンボルを提供します:

                 U Py_Finalize
                 U Py_Initialize
00000000002114a8 B PyOS_InputHook
                 U PyRun_InteractiveLoopFlags
                 U PyRun_SimpleStringFlags

PyOS_InputHookプラグインの BSS セクションで定義されていることがわかります。それでも、pythonreadline.soはそれを見つけることができません。

問題は、その理由と、それを修正する方法です。

4

1 に答える 1

0

問題は、メインアプリケーションがプラグインをロードする方法にあります。フラグRTLD_GLOBALなしでdlopen()を使用します。
これは、プラグインに存在し、現在必要とされていないシンボル(このインスタンスのPyOS_InputHookなど)は解決されず、後でロードされる他の共有ライブラリ(このインスタンスのreadline.soなど)では解決されないことを意味します。

これを修正するには、プラグインをロードするときにフラグRTLD_GLOBALを使用する必要があります。
メインアプリケーション(この例のように)とそれがdlopen()をどのように使用するかを制御できない場合でも、フラグRTLD_NOLOAD |を指定したdlopen()を使用して、プラグイン自体からプラグインを「再ロード」することができます。RTLD_GLOBAL。現在ロードされているライブラリ内の以前に解決されていないすべてのシンボルを解決します。

これを行うと問題が解決します。

于 2013-03-23T22:26:18.030 に答える