未定义的符号:PyOS_InputHook,来自共享库

时间:2013-03-23 21:33:32

标签: python plugins readline dlopen

我为一个非python C ++应用程序编写了一个C ++“python插件” 在某些时候,这个插件是一个.so,初始化python解释器并打开一个python控制台 为方便起见,然后导入“readline”模块,我们收到此错误:

ImportError:/usr/lib/python2.7/lib-dynload/readline.so:undefined symbol: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 [sources] [qt libs] -lGLU -lGL -lX11 -lXext -lc -lc -lpython2.7 -Wl,-rpath,/ src:/usr/local/Trolltech/Qt-4.8 0.4 / lib中:

nm libMyplugin.so给出以下与python相关的符号:

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

我们观察到插件的BSS部分中定义了PyOS_InputHook。然而,python的readline.so无法找到它。

问题是为什么以及如何解决它。

1 个答案:

答案 0 :(得分:0)

问题在于主应用程序如何加载插件:它使用dlopen()而没有标记RTLD_GLOBAL。
这意味着插件中存在的当前不需要的符号(如本例中的PyOS_InputHook)不会被解析,也不会被解析为之后将加载的其他共享库(如本例中的readline.so)。

要解决此问题,请在加载插件时使用标记RTLD_GLOBAL 如果无法控制主应用程序(如本例所示)以及它如何使用dlopen(),则仍然可以使用带有标记RTLD_NOLOAD的dlopen()从插件本身“重新加载”插件。 RTLD_GLOBAL,以便解析当前加载的库中所有以前未解析的符号。

这样做可以解决问题。