Linux中 靜態庫和共用庫

來源:互聯網
上載者:User

1. 建立目錄
 mkdir –p test/sub

2. 在子目錄sub/下編寫hello.c和hello.h
 /*****hello.c*****/
 #include <stdio.h>
 #include “hello.h”
 void hello()
 {
 printf(“Hello!/n”);
 }
 
 /*****hello.h*****/
 #include <stdio.h>
 void hello();

3. 編譯連結/打包
 gcc –c hello.c –o hello.o
 ar cqs libhello.a hello.o

4. 在主目錄test/下編寫main.c
 #include <stdio.h>
 #include “sub/hello.h”
 int main()
 {
 hello();
 retrun 0;
 }

5. 編譯連結
 gcc –c main.c –o main.o
 gcc main.o –o main.exe –L “sub/” –lhello          #dynamically linked (uses shared libs)
 或gcc main.o –o main.exe –static –L “sub/” –lhello  # statically linked

--------------------------------------------------------------------------------------------------

.a(archive)  靜態庫   
.so(shared object) 共用庫
靜態庫只在程式連結時起作用,最終的執行程式脫離靜態庫運行。
共用庫在程式運行時起作用。

--------------------------------------------------------------------------------------------------

共用庫的編號約定

格式library_name.major_num.minor_num.patch_num
例如libminigui.so.2.0.0
major_num:當庫的變化達到了和以前的版本不能相容的成都時就要增加主要版本號
minor_num:當庫有了新變化又能和以前的版本保持相容時就只改變次版本號碼
patch_num:為修正庫中的錯誤而進行的改動則會改變補丁層級號,它又叫做發行號(release number)。
以_g和_p結尾的庫:
例如libminigui_g.a和libminigui_p.a

們是基本庫的特殊版本,基本庫為libminigui.a。以_g結尾的庫是調試庫,編入了特殊的符號和功能,增加了對採用了這個庫的應用程式的調試功
能。以_p結尾的庫是代碼剖析庫(profiling),它們包含的代碼和符號能進行複雜的代碼剖析和效能分析。你如果使用了這兩類庫,一旦完成了調試和
剖析工作,需要使用正常庫重新編譯你的程式。

--------------------------------------------------------------------------------------------------

庫操作的相關命令

nm
功能
列出編入目標檔案或二進位檔案的所有符號。用途一:查看程式調用什麼函數;用途二:查看一個給定的庫或目標檔案是否提供了所需的函數。

文法
nm [options] file

常用選項
-C 將符號名轉換為使用者級的名字。在讓C++函數名可讀方面特別有用。
-s 當用於.a檔案時,輸出把符號名映射到定義該符號的模組或成員名的索引。
-u 只顯示未定義的符號,即在被檢查的檔案外部定義的檔案。
-l  使用調試資訊輸出定義每個符號的行號,或未定義符號的重要位項。

ar
功能
將多個.o檔案組合到一起成為.a檔案。

文法
ar [options] lib*.a *.o

常用選項
-c 如果封存檔案不存在,則建立,並不顯示ar發出的警告。
-q 把*.o添加到封存檔案末尾而不檢查是否進行替換。
-r  向封存檔案中插入.o檔案,替換已有的任何同名檔案,新成員添加到文檔末尾。
-s 建立或升級從符號到.a檔案之間的交叉索引映射表,並加入到.a檔案中。
   等價與ranlib [*.a]。執行該命令後,可用nm –s來查看產生的索引。

ldd
功能
顯示可執行程式運行所需的共用庫。

文法
ldd [options] file

常用選項
-d 執行重定位並報告所有丟失的函數。
-r 執行對函數和資料對象的重定位並報告丟失的任何函數或資料對象。

ldconfig
功能
在預設搜尋目錄(/lib和/usr/lib)及動態庫設定檔/etc/ld.so.conf中所列的目錄
下,搜尋出可共用的動態連結程式庫(lib*.so*),進而建立出動態裝入程式(ld.so)所需的串連和快取檔案。快取檔案預設為
/etc/ld.so.cache,此檔案儲存了已排好序的動態連結程式庫名字列表。
該在系統啟動時會運行,而當使用者安裝了一個新的動態連結程式庫時,就需要手工運行這個命令。

文法
ldconfig [options] path
例如:ldconfig /root/lib
讓系統共用/root/lib目錄下的動態連結程式庫,即在/etc/ld.so.cache中添加指定目錄下的共用庫。[注意]若該目錄不在/lib,
/usr/lib,/etc/ld.soconf所列的目錄列表裡,則再次運行ldconf時,此目錄下的動態連結程式庫就不被系統共用了。

常用選項
-v 更新/etc/ld.so.cache的內容,列處每個庫的版本號碼,掃描的目錄和所有建立和更新的連結。
-p 僅顯示/etc/ld.so.cache的內容,即ld.so所知道的共用庫的當前列表。
-n  ldconf僅掃描-n命令所指定的目錄
-f CONF   指定動態連結程式庫的設定檔為CONF,系統預設為/etc/ld.so.conf。
-c CACHE  指定產生的快取檔案為CACHE,系統預設為/etc/ld.so.cache。
當ldconf不帶選項時,僅更新高速緩衝檔案。 

環境變數
$LD_PRELOAD      由空格分隔的共用庫列表,在其它庫之前載入,使它們有機會覆蓋或
                    重新定義標準庫。
$LD_LIBRARY_PATH 由冒號分隔的目錄清單,都是共用庫搜尋時會訪問的目錄。

--------------------------------------------------------------------------------------------------

建立和使用動態庫

建立動態庫
1. gcc –fPIC –c hello.c –o hello.o
2. gcc –shared –Wl,-soname,libhello.so –o libhello.1.0.0 hello.o –lc
參數說明
-fPIC   產生與位置無關的代碼,並能載入到任何位置。-fpic與之相似,會產生更小更快的
        代碼,但會有平台的限制。
-shared  告訴編譯器產生共用庫代碼。
-Wl     告訴編譯器將後面的參數傳給連結器ld。
-soname 指定了共用庫的簡寫共用名稱(short for shared object name)。
-l       指定連結的庫檔案名稱。
-L      向gcc的庫檔案搜尋路徑中添加新的目錄

使用動態庫
方法一
1) 將產生的.so檔案複製到系統預設的存放庫檔案的檔案夾,如/usr/lib。如果你複製
    libhello.so.1.0.0到/usr/lib,會自動產生一個它的符號連結libhello.so。
2) 以root身份運行ldconfig,更新高速緩衝區/etc/ld.so.cache。
3) gcc –c main.c –o main –lhello
方法二
1) 改變環境變數$LD_LIBRARY_PATH=”your dir”
2) gcc –c main.c –o main –L “sub” –lhello
方法三
1) 在/etc/ld.so.conf中添加你的共用庫所在的路徑
2) 以root使用者身份運行ldconfig
3) gcc –c main.c –o main –L “sub” -lhello

--------------------------------------------------------------------------------------------------

使用動態載入的共用對象

只需在源碼中包含<dlfcn.h>,然後在編譯命令或makefile中使用-ldl命令與libdl庫連結即可。
[注意]不必連結你要使用的庫。即使使用一個標準的共用庫,也不必按常規方法使用,連結器不會知道共用對象。在編譯連結應用程式時,這些模組甚至可以不存在。

dlopen
載入共用對象。如果找到了filename就返回控制代碼,否則返回NULL。
void *dlopen (const char *filename, int flag);

dlsym
使用共用對象。dlsym在載入對象(由handle指向的共用對象)中搜尋在symbol中命名的符號或函數。參數handle須是dlopen返回的控制代碼;參數symbol是一個標準的C字串。dlsym
返回指向符號的null 指標,若發生錯誤則返回NULL。
void *dlsym (void *handle, char *symbol)

dlerror
檢查錯誤。如果任何函數出錯,dlerror返回一個描述錯誤的字串,再把錯誤的字串置為NULL。
const char *dlerror (void);

dlclose
卸載共用庫。確定不再需要某個共用對象後,關閉它以節省系統資源。
int dlclose (void *handle);

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.