我为一个非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
无法找到它。
问题是为什么以及如何解决它。
答案 0 :(得分:0)
问题在于主应用程序如何加载插件:它使用dlopen()而没有标记RTLD_GLOBAL。
这意味着插件中存在的当前不需要的符号(如本例中的PyOS_InputHook)不会被解析,也不会被解析为之后将加载的其他共享库(如本例中的readline.so)。
要解决此问题,请在加载插件时使用标记RTLD_GLOBAL 如果无法控制主应用程序(如本例所示)以及它如何使用dlopen(),则仍然可以使用带有标记RTLD_NOLOAD的dlopen()从插件本身“重新加载”插件。 RTLD_GLOBAL,以便解析当前加载的库中所有以前未解析的符号。
这样做可以解决问题。