C邊角料4 C基礎之自製靜態庫,動態庫

2021-10-19 09:37:42 字數 3361 閱讀 4604

c基礎之自製靜態庫,動態庫

前言 c基礎文章**

發布版本包含.a檔案和.h標頭檔案。.c檔案不會給別人

我們選擇寫乙個makefile,這樣可以將編譯的過程記錄下來。

all:

gcc richard.c -o richard.o -c

ar -rc librichard.a richard.o

(1)第一步:自己製作靜態鏈結庫

首先使用gcc -c只編譯不連線,生成.o檔案;

然後使用ar工具進行打包成.a歸檔檔案

庫名不能隨便亂起,一般是lib+庫名稱,字尾名是.a表示是乙個歸檔檔案

注意:製作出來了靜態庫之後,發布時需要發布.a檔案和.**件。

將要發布的檔案打包到testlib資料夾中,此資料夾是使用者方自己寫的檔案和提供方發布的檔案,類似於購買軟體,自己寫個.c檔案,然後在商家手中買來.h和.a檔案,可以在.c檔案中使用購買的檔案。

(2)第二步:使用靜態鏈結庫

把.a和.h都放在我引用的資料夾下,然後在.c檔案中包含庫的.h,然後直接使用庫函式。

第一次,編譯方法:gcc test.c -o test

報錯資訊:test.c:(.text+0xa): undefined reference tofunc1' test.c:(.text+0x1e): undefined reference tofunc2』

第二次,編譯方法:gcc test.c -o test -lrichard

報錯資訊:/usr/bin/ld: cannot find -lrichard

collect2: error: ld returned 1 exit status

第三次,編譯方法:gcc test.c -o test -lrichard -l. //-l告訴聯結器在哪個庫中找,後面跟庫的名字。-l就是告訴聯結器到哪個目錄去找,.表示在當前目錄,所以-l.表示在當前目錄找。

無報錯,生成test,執行正確。

(3)除了ar,命令外,還有個nm命令也很有用,它可以用來檢視乙個.a檔案中都有哪些符號

動/靜態鏈結庫製作原始檔:

(1)動態鏈結庫的字尾名是.so(對應windows系統中的dll),靜態庫的副檔名是.a

(2)第一步:建立乙個動態鏈結庫。

gcc richard.c -o richard.o -c -fpic

gcc -o librichard.so richard.o -shared

(position independent code位置無關碼,因為動態鏈結庫都是位置無關碼)

-fpic是位置無關碼,-shared是按照共享庫(動態鏈結庫)的方式來鏈結。

注意:做庫的人給用庫的人發布庫時,發布lib***.so和***.h即可。

(3)第二步:使用自己建立的共享庫。

第一步,編譯方法:gcc test.c -o test

報錯資訊:test.c:(.text+0xa): undefined reference tofunc1' test.c:(.text+0x1e): undefined reference tofunc2』

collect2: error: ld returned 1 exit status

第二步,編譯方法:gcc test.c -o test -lrichard

報錯資訊:/usr/bin/ld: cannot find -lrichard

collect2: error: ld returned 1 exit status

第三步,編譯方法:gcc test.c -o test -lrichard -l.

編譯成功

但是執行出錯,報錯資訊:

error while loading shared libraries: librichard.so: cannot open shared object file: no such file or directory

錯誤原因:動態鏈結庫執行時需要被載入(執行時環境在執行test程式的時候發現他動態鏈結了librichard.so,於是乎會去固定目錄嘗試載入librichard.so,如果載入失敗則會列印以上錯誤資訊。)

解決方法一:

將librichard.so放到固定目錄下就可以了,這個固定目錄一般是/usr/lib目錄。

cp librichard.so /usr/lib即可

解決方法二:使用環境變數ld_library_path。作業系統在載入固定目錄/usr/lib之前,會先去ld_library_path這個環境變數所指定的目錄下去尋找,如果找到就不用去/usr/lib下面找了,如果沒找到再去/usr/lib下面找。所以解決方案就是將librichard.so所在的目錄匯出到環境變數ld_library_path中即可。

export ld_library_path=$ld_library_path:/mnt/hgfs/winshare/s5pv210/advancedc/preprocessfunction/12.sharedobject.c/sotest

可以用echo $ld_library_path來檢視匯出的目錄

在ubuntu中還有個解決方案三,用ldconfig

(4)ldd命令:作用是可以在乙個使用了共享庫的程式執行之前解析出這個程式使用了哪些共享庫,並且檢視這些共享庫是否能被找到,能被解析(決定這個程式是否能正確執行)。

ldd後得到類似如下結果:

linux-gate.so.1 =

>

(0xb770f000)

librichard.so (0xb770b000)

libc.so.6 =

> /lib/i386-linux-gnu/libc.so.6 (0xb7546000)

/lib/ld-linux.so.2 (0xb7710000)

可以看到librichard.so是可以連線到的

如果將librichard.so所在的目錄匯出到環境變數ld_library_path中,命令如下:export ld_library_path= 則ldd得到結果:

linux-gate.so.1 =

>

(0xb7710000)

librichard.so =

> not found

libc.so.6 =

> /lib/i386-linux-gnu/libc.so.6 (0xb754a000)

/lib/ld-linux.so.2 (0xb7711000)

librichard.so連線未找到檔案。

C語言邊角料2 用純軟體來代替Mutex互斥鎖

目錄 五 總結 在 linux 系統中,當多個執行緒並行執行時,如果需要訪問同乙個資源,那麼在訪問資源的地方,需要使用作業系統為我們提供的同步原語來進行保護。同步原語包括 互斥鎖 條件變數 訊號量等,被保護的 稱作 臨界區 這是非常正規的流程,我們基本上也都是這麼做的。那有沒有想過,這些同步原語對 ...

練習4 c 基礎

using system using system.collections.generic using system.linq using system.text namespace列舉 列舉可用來儲存字串與數字的值對,相當於乙個對照表 常用方法 getname getvalue parse 宣告乙...

C 學習筆記4 C 之bool型別

c 中的bool型別 c 在c語言的基本型別系統上增加了bool型別 c 中的bool可取的值只有true與false 理論上bool值佔乙個位元組 如果多個bool值定義在一起,可能各佔乙個bit,這取決於編譯器的實現 true代表真值,編譯器內部用1來表示 false代表非真值,編譯器內部用0來...