2013-03-23 55 views
0

我爲非python C++應用程序編寫了一個C++「python插件」。
在某些時候,這個插件是.so,它初始化python解釋器並打開一個python控制檯。
爲了方便 「的ReadLine」 模塊,然後導入,我們得到這個錯誤:未定義的符號:PyOS_InputHook,來自共享庫

導入錯誤:/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 [sources] [qt libs] -lGLU -lGL -lX11 -lXext -lc -lc -lpython2.7 -Wl,-rpath,/ src:/usr/local/Trolltech/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_InputHook在插件中的BSS部分定義。然而,python的readline.so未能找到它。

問題是爲什麼,以及如何解決它。

+0

一種可能的解釋:當主應用程序使用dlopen()加載插件時,它可能會使用RTLD_GLOBAL的某個標誌RTLD_LOCAL intead。然後符號不會被提供給.so隨後加載(如readline.so)。要驗證... – user2179288 2013-03-23 21:36:49

+0

其實,PyOS_InputHook最初並不存在於libMyplugin.so中,它也不能工作。之後我在插件代碼源中添加了這種符號的定義,以查看它是否有幫助。它不是。 – user2179288 2013-03-23 22:01:13

回答

0

問題在於主應用程序如何加載插件:它使用dlopen(),而不使用標誌RTLD_GLOBAL。
這意味着當前不需要的插件中的符號(如本例中的PyOS_InputHook)不會被解析,並且不會解析其他將在稍後加載的共享庫(如本例中的readline.so)。

爲了解決這個問題,應該在加載插件時使用標誌RTLD_GLOBAL。
如果沒有對主應用程序的控制權(如本例中)以及它如何使用dlopen(),仍然可以使用帶標誌的dlopen()從插件本身「重新加載」插件RTLD_NOLOAD | RTLD_GLOBAL,以便解析當前加載的庫中所有以前未解析的符號。

這樣做解決了這個問題。