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 回答