2014-05-06 62 views
5

如果您有確實有經驗與上述標題相關,您是否願意留下您的評論?我試圖做一個共享對象被延遲加載都鏘和GCC在Ubuntu(其實我不介意使用哪個編譯器),但他們並不看起來非常支持任何延遲加載功能(我的預期延遲加載功能將一個存根放在一個父對象中,該對象試圖按需加載另一個對象,此時該功能是必需的,但實際上並沒有)。以下命令顯示,我試圖讓libbar.so被延遲加載到對libfoo.so:Clang/GCC是否真的支持延遲加載功能?

clang bar.c -fPIC -shared -o libbar.so 
clang foo.c -Wl,-zlazy,lL'/path/to/where/lib/is',-lbar -o foo 

你會看到libfoo.so進入到入口如果libbar.so不前引發異常不存在。反正,我不介意,如果有上面的命令任何錯字,但想知道鏘/ GCC真正支持延遲加載功能,或者不。但是,就個人而言,如果Clang/GCC不支持任何延遲加載功能,我不能相信Linux程序開發人員是否需要調用dlopen()或dlsym()來使共享對象延遲加載。如果對象是用C編寫的,但是如果它是用C++編寫的,情況可能會好起來,但情況必須完全複雜:我相信一個在編譯器或鏈接器的幫助下實現的解決方案是最好的,因爲我已經成功地與Windows和Mac OS做到了。所以我覺得這將是其中的公民都想做夢有一個延遲加載功能,即使是在鐺/ GCC的自然反應。我還可以,如果您有任何評論欣賞我的感覺。

PS。我知道的Solaris支持延遲加載功能,但是這不是很長的路要走我,因爲我將不制定任何事情。

無論如何,非常感謝你提前。

+0

是的,這可以在Linux上完成。 – kec

+0

@ kec,謝謝。你的意思是GCC/Clang可以通過傳遞一些選項來讓共享對象延遲加載嗎?任何官方文檔是否描述瞭如何使用它?很高興知道你能否解釋爲什麼我得到了上述結果。 – Doofah

+0

其實在重讀之後,我不確定我是否知道你在說什麼。你在談論dlopen()嗎?你想要發生什麼? – kec

回答

10

這是更由運行時鏈接,ld-linux.so提供的功能性的問題。

此連接不支持延遲綁定的符號,但圖書館沒有延遲加載。這意味着當程序啓動時,可執行文件所需的每個共享對象都會被加載,但程序中的符號在第一次被引用之前不會被解析到加載的庫中。

這樣做的原因是性能。一個庫可能包含數千個函數的符號,這些函數在程序的單個執行過程中永遠不會被調用。解決它們都是浪費時間。由於這個原因,如果一個庫不包含預期的符號,在程序開始運行後,你可以很好地得到'未定義的符號'的錯誤,但是如果一個庫完全缺失,你會在程序出現之前得到一個錯誤開始。

您引用的-zlazy選項僅控制延遲符號綁定。實際上它是默認啓用的(至少對於GCC來說,我沒有檢查clang)。

在程序啓動後加載庫(例如響應某些命令行選項,配置或其他動態條件)的唯一方法是致電dlopen

你可能想看看周圍有一個良好的插件框架 - 對參考文獻,參見:

+0

@ harmic,感謝您留下您的評論。它回答了我錯誤地做了什麼。我會閱讀你上面發佈的參考文獻。再次感謝你! :) – Doofah

+0

@ harmic,我猶豫使用dlopen方式的原因是它實現起來很複雜。實際上,我確認它使用一個非常簡單的C++程序(它調用從dlsym()返回的類指針獲取的類的成員函數)。但是,如果我試圖將該技術應用於第三方庫(與我測試的教程相比,這個技術越來越複雜),一切都變得瘋狂...... – Doofah

+0

@ user3591878很難從這個描述中瞭解問題所在!我建議你把它作爲一個單獨的問題發佈。包括可導致「瘋狂」行爲的最小示例程序。 – harmic

0

Linux不支持庫的延遲加載了的框,但它可以很容易地實現使用相同的機制,在Windows上使用,即通過鏈接到小stub st其中dlopen是首次調用其任何函數的主共享庫。

您可以實現用手這樣存根庫,通過自定義腳本爲您量身定做的項目,或使用Implib.so自動生成它:

$ clang bar.c -fPIC -shared -o libbar.so 
$ gen-implib.py libbar.so 
$ clang foo.c libbar.tramp.S libbar.init.c -o foo