2009-08-17 107 views
6

我有一個程序,通過動態加載一個plugin_name.so函數來實現一個插件系統(像往常一樣)。GCC/Linux:將靜態庫添加到.so?

但反過來,我有一個靜態的「助手」庫(可以稱之爲helper.a),它的功能既用於主程序又用於插件的主要功能。它們不必以任何方式進行互操作,它們只是用於文本操作等的輔助函數。

該程序一旦啓動就無法重新加載或重新啓動,這就是爲什麼我期望從插件獲得新的「幫助」功能,而不是來自主程序。

所以我的questin是..是否有可能在.so中強制使用(靜態鏈接?)與主程序不同(可能更新版本)的「助手」版本中的「插件函數代碼」?

這怎麼辦?也許通過靜態鏈接或以其他方式將helper.a添加到plugin_name.so?

+0

我想補充一點,我不想要或希望從主程序使用新的輔助庫..我只是想每一個新的插件有新/更好的幫手庫鏈接。 – conejoroy 2009-08-18 00:10:31

+0

是否有一個原因,你不能使用助手功能的動態鏈接? – 2009-08-18 01:31:01

+0

一旦啓動,主程序無法停止執行,甚至無法重新加載新的helper.so ..並且該程序只需要非常基本的幫助程序功能,因爲它只是插件的佔位符。所以如果我有一個新的/改進或擴展的幫助程序庫,我更願意再次編譯整個插件。我認爲分發一個.so(插件)比兩個.so(插件和最新的插件使用的輔助工具)要更實用 – conejoroy 2009-08-18 04:46:54

回答

6

Nick Meyer的答案在Windows和AIX上是正確的,但在默認情況下在其他任何UNIX平臺上不太可能正確。

在大多數UNIX平臺上,運行時加載器維護的所有符號的命名空間,所以如果你在a.outplugin.so定義foo_helper,而且,然後調用foo_helper從任,第一個定義可見的運行時間裝載程序(通常來自a.out)默認情況下用於兩個調用。

此外,畫面是由以下事實:foo_helper可能無法從a.out出口(並且因此可能是不可見的運行時加載器)複雜的,除非使用-rdynamic標誌,或一些其它共享庫引用它。換句話說,可能出現工作,因爲尼克描述他們,然後你將一個共享庫添加到a.out鏈接線,他們不再那樣工作。

在ELF平臺(如Linux)上,您可以很好地控制符號可見性和綁定。請參閱GCC手冊頁中的-fvisibility=hidden-rdynamic以及鏈接器手冊頁中的-Bsymbolic的描述。

大多數其他UNIX平臺也有一些控制符號綁定的方法,但這必須是平臺特定的。

1

如果你的主程序和動態庫都靜態鏈接到helper.a,那麼你不需要擔心混合版本的helper.a(只要你不需要像helper中分配的指針那樣的事情.exe和.so之間的邊界)。

當您鏈接到它時,helper.a所需的代碼被插入到實際的二進制文件中。因此,當您從.exe調用helper.a時,您將執行可執行映像的代碼段中的代碼,並且當您從.so調用helper.a時,您將執行代碼的部分代碼地址空間.so被加載。即使你在helper.a中調用了相同的函數,你也可以調用該函數的兩個不同的「實例」,具體取決於調用是由.exe還是.so調用的。

+0

我明白了。但是如何在編譯時將libhelper.a中的代碼添加到plugin.so?我應該在編譯plugin.so時指定「gcc -lhelper.a -static」之類的東西嗎? – conejoroy 2009-08-18 00:27:30

+0

如果您的庫是libhelper.a,那麼在編譯plugin.so時將-L * dir * -helper傳遞給gcc,其中* dir *是libhelper.a的路徑。不需要指定-static,這是在創建靜態庫時使用的。 – 2009-08-18 01:43:27

+0

只有在沒有說明的有限條件下,此答案纔是正確的。 – 2009-08-18 06:21:08