dlopen 打開依賴本應用程序的某些函數的庫時的注意事項

原文地址: http://blog.csdn.net/lp525110627/article/details/53148605


一、“--export-dynamic”參數的使用

GCC編譯可執行文件時可以使用-Wl,--export-dynamic參數,此時鏈接器產生可執行文件時會將所有全局符號導出到動態符號表。

gcc -Wl,--export-dynamic -o p1 p1.c -L. -l0

如果在創建動態鏈接的可執行文件不加-Wl,--export-dynamic選項,則它所export的動態符號僅僅包括在鏈接時動態對象所用到的。因爲dlopen是自行加載動態庫,並不存在與可執行文件動態符號解析的過程,所以如果dlopen加載的動態庫使用了主模塊中定義的函數,則會出現找不到符號的情況。

默認鏈接器在產生可執行文件時,只會將那些鏈接時被其他共享模塊引用到的符號放到動態符號表中,這樣可以減少動態符號表的大小,也就是說,在共享模塊中反向引用主模塊中的符號時,只有那些在鏈接時被共享模塊引用到的符號纔會被導出,(主模塊的符號表中依賴的共享模塊主模塊纔會去鏈接,否則不會去鏈接,不被鏈接的模塊引用了主模塊的符號就不會被導出到動態符號表中,導致運行時報錯)。

但是使用--export-dynamic參數後由於將所有的全局符號導出到動態符號表中導致可執行程序會變大。

二、strip清除符號信息

正常情況下編譯出來的共享庫和可執行文件中都帶有符號信息和調試信息,但是發佈版本一般不需要這些信息。且這些信息會導致可執行文件大一倍多,所以可以使用strip命令去掉調試信息:strip liba.so

ld的“-S”和“-s”也能使鏈接器輸出的可執行文件不產生調試信息,“-S”消除調試符號信息,“-s”消除所有符號信息。

gcc -WI,-s a.out或gcc -WI,-S a.out

三、共享庫的安裝部署

1、設置環境變量LD_LIBRARY_PATH

export LD_LIBRARY_PATH=/home/work/deal/dynamic

export LD_LIBRARY_PATH=$(pwd)

2、使用鏈接器的“-rpath”選項,可以指定鏈接器產生的目標文件的共享庫查找路徑。

ld -rpath /home/lib -o a.out a.o -lc

這樣參數的a.out首先會在/home/lib目錄下查找共享庫,可以使用“-L”,“-l”分別指定共享庫的搜索目錄和共享庫的路徑。

3、將共享庫複製到共享目錄中/lib /usr/lib然後運行ldconfig即可。需要root纔能有權限往lib下拷貝文件和運行ldconfig

4、建立相應的SO-NAME軟鏈接

GCC可以使用“-WI,-soname,my_soname”參數將my_soname傳遞給鏈接器,用來指定輸出共享庫的SO-NAME,如:

gcc -shared -WI,-soname,my_soname -o a.so a.c -lc

如果不使用-soname指定共享庫的SO-NAME,那麼默認共享庫就沒有SO-NAME,即使用ldconfig更新SO-NAME的軟鏈接時,對該庫也沒有效果。

使用ldconfig更新SO-NAME的軟鏈接命令:

ldconfig -n /home/lib

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章