ubuntu下生成靜態(tài),動(dòng)態(tài)庫(kù),并調(diào)用

首先我們通過三個(gè)文件生成一個(gè)對(duì)應(yīng)的so庫(kù),然后演示如何調(diào)用對(duì)應(yīng)的庫(kù)。生成對(duì)應(yīng)的五個(gè)文件,test_a.c,test_b,c,test_c.c,so_test.h,test.c。
<code>
so_test.h
#include "stdio.h"
void test_a();
void test_b();
void test_c();
</code>
<code>
test_a.c
#include "so_test.h"
void test_a()
{
printf("this is in test_a..\n");
}
</code>
<code>
test_b.c
#include "so_test.h"
void test_b()
{
printf("this is in test_b..\n");
}
</code>
<code>
test_c.c
#include "so_test.h"
void test_c()
{
printf("this is in test_c..\n");
}
</code>
<code>
test.c
#include "so_test.h"

int main()
{
test_a();
test_b();
test_c();
return 0;
}
</code>

生成動(dòng)態(tài)庫(kù)

編程三個(gè)文件生成so庫(kù),其中-shared指生成動(dòng)態(tài)庫(kù),-fPIC指生成的庫(kù)地址無關(guān)。
<code>gcc test_a.c test_b.c test_c.c -fPIC -shared -o libtest.so</code>
使用動(dòng)態(tài)庫(kù)
<code>gcc -o test test.c -L. -ltest</code>
但是此時(shí)如果使用ldd或者運(yùn)行test程序的話,就會(huì)發(fā)現(xiàn)程序還是運(yùn)行不了。
<code>crystal@crystal:~/workspace/sotest$ ldd test
linux-vdso.so.1 => (0x00007ffea3b8a000)
libtest.so => not found
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f095aa14000)
/lib64/ld-linux-x86-64.so.2 (0x00005564bf151000)</code>
這個(gè)因?yàn)槲覀儌€(gè)人的so庫(kù),并不能被系統(tǒng)直接識(shí)別,需要執(zhí)行LD_LIBRARY_PATH
或者在/etc/ld.so.conf.d目錄下面添加對(duì)應(yīng)的庫(kù)項(xiàng)。
執(zhí)行<code>
export LD_LIBRARY_PATH=$(pwd)
</code>然后重新運(yùn)行程序。但是每次都這樣會(huì)顯得很麻煩,這是我們可以把我們放置so的目錄添加到/etc/ld.so.conf.d/目錄下面去,然后執(zhí)行ldconfig命令
<code>
crystal@crystal:~/workspace/sotest$ sudo vim /etc/ld.so.conf.d/test.conf
crystal@crystal:~/workspace/sotest$ cat /etc/ld.so.conf.d/test.conf
/home/crystal/workspace/sotest
crystal@crystal:~/workspace/sotest$ sudo ldconfig
crystal@crystal:~/workspace/sotest$ ./test
this is in test_a..
this is in test_b..
this is in test_c..</code>

生成靜態(tài)庫(kù)

生成對(duì)應(yīng)的三個(gè).o文件
<code>gcc -c test_a.c test_b.c test_c.c </code>
生成libtest.a靜態(tài)庫(kù)
<code>ar rcs libtest.a test_a.o test_b.o test_c.o</code>
使用靜態(tài)庫(kù)
<code>gcc -o test test.c -static -L. -ltest</code>
然后運(yùn)行和查看程序
<code>crystal@crystal:~/workspace/sotest$ ./test
this is in test_a..
this is in test_b..
this is in test_c..
crystal@crystal:~/workspace/sotest$ ldd test
不是動(dòng)態(tài)可執(zhí)行文件</code>
此時(shí)如果刪除libtest.a文件程序也是可以正常運(yùn)行的,并且test可執(zhí)行程序會(huì)比其他動(dòng)態(tài)可執(zhí)行文件大很多。

NOTE

****編譯參數(shù)解析
**
最主要的是GCC命令行的一個(gè)選項(xiàng):-shared 該選項(xiàng)指定生成動(dòng)態(tài)連接庫(kù)(讓連接器生成T類型的導(dǎo)出符號(hào)表,有時(shí)候也生成弱連接W類型的導(dǎo)出符號(hào)),不用該標(biāo)志外部程序無法連接。相當(dāng)于一個(gè)可執(zhí)行文件

  • -fPIC:表示編譯為位置獨(dú)立的代碼,不用此選項(xiàng)的話編譯后的代碼是位置相關(guān)的所以動(dòng)態(tài)載入時(shí)是通過代碼拷貝的方式來滿足不同進(jìn)程的需要,而不能達(dá)到真正代碼段共享的目的。
  • -L.:表示要連接的庫(kù)在當(dāng)前目錄中
  • -ltest:編譯器查找動(dòng)態(tài)連接庫(kù)時(shí)有隱含的命名規(guī)則,即在給出的名字前面加上lib,后面加上.so來確定庫(kù)的名稱l LD_LIBRARY_PATH:這個(gè)環(huán)境變量指示動(dòng)態(tài)連接器可以裝載動(dòng)態(tài)庫(kù)的路徑。
  • 當(dāng)然如果有root權(quán)限的話,可以修改/etc/ld.so.conf文件,然后調(diào)用 /sbin/ldconfig來達(dá)到同樣的目的,不過如果沒有root權(quán)限,那么只能采用輸出LD_LIBRARY_PATH的方法了。
    調(diào)用動(dòng)態(tài)庫(kù)的時(shí)候有幾個(gè)問題會(huì)經(jīng)常碰到,有時(shí),明明已經(jīng)將庫(kù)的頭文件所在目錄 通過 “-I” include進(jìn)來了,庫(kù)所在文件通過 “-L”參數(shù)引導(dǎo),并指定了“-l”的庫(kù)名,但通過ldd命令察看時(shí),就是死活找不到你指定鏈接的so文件,這時(shí)你要作的就是通過修改 LD_LIBRARY_PATH或者/etc/ld.so.conf文件來指定動(dòng)態(tài)庫(kù)的目錄。通常這樣做就可以解決庫(kù)無法鏈接的問題了。
    靜態(tài)庫(kù)鏈接時(shí)搜索路徑順序:
  • ld會(huì)去找GCC命令中的參數(shù)-L2. 再找gcc的環(huán)境變量LIBRARY_PATH3. 再找內(nèi)定目錄 /lib /usr/lib /usr/local/lib 這是當(dāng)初compile gcc時(shí)寫在程序內(nèi)的
    動(dòng)態(tài)鏈接時(shí)、執(zhí)行時(shí)搜索路徑順序:
  • 編譯目標(biāo)代碼時(shí)指定的動(dòng)態(tài)庫(kù)搜索路徑;
  • 環(huán)境變量LD_LIBRARY_PATH指定的動(dòng)態(tài)庫(kù)搜索路徑;
  1. 配置文件/etc/ld.so.conf中指定的動(dòng)態(tài)庫(kù)搜索路徑;
  2. 默認(rèn)的動(dòng)態(tài)庫(kù)搜索路徑/lib;
  3. 默認(rèn)的動(dòng)態(tài)庫(kù)搜索路徑/usr/lib。
    有關(guān)環(huán)境變量:
    LIBRARY_PATH環(huán)境變量:指定程序靜態(tài)鏈接庫(kù)文件搜索路徑LD_LIBRARY_PATH環(huán)境變量:指定程序動(dòng)態(tài)鏈接庫(kù)文件搜索路徑
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容