未定义符号:PyOS_InputHook,来自共享库 我为一个非Python C++应用程序编写了一个C++“Python插件”。 在某种程度上,这个插件是一个.so,它初始化python解释器并打开一个python控制台。 为方便起见,随后导入“readline”模块,我们得到以下错误:

未定义符号:PyOS_InputHook,来自共享库 我为一个非Python C++应用程序编写了一个C++“Python插件”。 在某种程度上,这个插件是一个.so,它初始化python解释器并打开一个python控制台。 为方便起见,随后导入“readline”模块,我们得到以下错误:,python,plugins,readline,dlopen,Python,Plugins,Readline,Dlopen,importorror:/usr/lib/python2.7/lib-dynload/readline.so:未定义的符号:PyOS\u InputHook 链接命令(由cmake生成)如下所示: /usr/bin/c++-fPIC-Wall-Wextra-O3-DNDEBUG-Xlinker-export dynamic-Wl-fwhere程序/usr/lib/libpython2.7.a-shared-Wl-soname,libMyplugin.so-o libMyplugin.so[sou

importorror:/usr/lib/python2.7/lib-dynload/readline.so:未定义的符号:PyOS\u InputHook

链接命令(由cmake生成)如下所示:

/usr/bin/c++-fPIC-Wall-Wextra-O3-DNDEBUG-Xlinker-export dynamic-Wl-fwhere程序/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/trolletech/qt/qt-4.8.4/lib:

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

                 U Py_Finalize
                 U Py_Initialize
00000000002114a8 B PyOS_InputHook
                 U PyRun_InteractiveLoopFlags
                 U PyRun_SimpleStringFlags
我们观察到,
PyOS\u InputHook
是在插件的BSS部分定义的。然而,python的
readline.so
无法找到它


问题是为什么,以及如何修复它。

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

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


这样做可以解决问题。

一种可能的解释是:当主应用程序使用dlopen()加载插件时,它可能会使用RTLD_LOCAL intead或RTLD_GLOBAL的一些标志。然后符号将无法用于随后加载的.so(如readline.so)。需要验证的是…实际上,PyOS_InputHook最初并不存在于libMyplugin.so中,而且也不起作用。后来我在插件代码源代码中添加了这个符号的定义,看看它是否有用。事实并非如此。