linux 靜態庫動態庫封裝問題
在Linux下類庫主要有靜態庫和動態庫兩種庫,首先呢,就說說這兩種庫的差異:
靜態庫:
在程式連線的時候會自動的連線到程式裡,
所以一但編譯完成,靜態庫也就不需要了。靜態庫通常以.a結尾。
例如:libutil.a libuuid.a libz.a等。
動態庫:
在程式編譯時並不會被連線到目的碼中,而是在程式執行是才被載入,
因此在程式執行時還需要動態庫存在。通常以.so結尾。如:libz.so。
因此,靜態庫相對於共享庫來說有更高的效率但是也要消耗更多的空間。
值得注意的是,如果既有靜態庫又有動態庫,在編譯時預設的使用動態庫。
在建立自己的靜態庫或者動態庫時候我想,絕大部分人也都會覺得很輕鬆,下面就直接貼步驟
靜態庫:
(1) 編寫庫檔案testlib.c
(2)編寫一個頭檔案用於宣告我們使用的函式testlib.h
(3) 編譯testlib.c:
gcc -c testlib.c
(4) 用ar建立一個歸檔檔案:
ar crv libfirst.a testlib.o 生成libfirst.a
(5)在某些系統中還要為靜態庫生成一個內容表
ranlib libfirst.a
(6)然後就可以使用該靜態庫了
eg:
[
[[email protected] Source]# gcc -o zyx zyx.c -I./lib -L./lib -lfirst (-static)
[[email protected] Source]# ls
hello HelloWorld.h static.exe zyx
HelloWorld.cpp lib StaticLibTest.c zyx.c
[
動態庫:
通過一個例子來介紹如何生成一個動態庫。這裡有一個頭檔案:so_test.h, 三個.c檔案:test_a.c、test_b.c、test_c.c
我們將這幾個檔案編譯成一個動態庫:libtest.so。
gcc test_a.c test_b.c test_c.c -fPIC -shared -o libtest.so
我們已經成功生成了一個自己的動態連結庫libtest.so,
下面我們通過一個程式來呼叫這個庫裡的函式。假設程式的原始檔為:test.c
將test.c與動態庫libtest.so連結生成執行檔案test: $ gcc test.c -L. -ltest -o test
測試是否動態連線,如果列出libtest.so,那麼應該是連線正常了
在使用動態庫的時候,還有一點會經常遇到的需要注意:
呼叫動態庫的時候有幾個問題會經常碰到,有時,明明已經將庫的標頭檔案所在目錄
通過 “-I” include進來了,庫所在檔案通過 “-L”引數引導,並指定了“-l”
的庫名,但通過ldd命令察看時,就是死活找不到你指定連結的so檔案,這時你要作
的就是通過修改LD_LIBRARY_PATH或者/etc/ld.so.conf檔案來指定動態庫的目錄。
通常這樣做就可以解決庫無法連結的問題了
1.修改/etc/ld.so.conf,加入自己的動態庫的路徑
然後/sbin/ldconfig 使配製檔案生效
2。直接把自己的動態庫檔案拷貝到 /etc/ld.so.conf中的任意路徑
3.export LD_LIBRARY_PATH=/home/kui/:$LD_LIBRARY_PAT(=的前後不能有空格)或者export
$LD_LIBRARY_PATH:LD_LIBRARY_PATH=/home/kui/
使用echo $LD_LIBRARY_PATH可以看到路徑是否設定成功
上面這些都是最基本的,在工作中,這些往往滿足不了我們的需要,比如說,我們生成一個動態庫,要依賴與多個動態庫或者靜態庫,或者我生成靜態庫的時候要依賴於其它的靜態庫,這個時候怎麼弄?
關於依賴於多個靜態庫或者動態庫生成一個動態庫的,網上有很多資源,也不多說,直接貼一個示例:
gcc -g Protocol.c -fPIC -shared libadd.a libade.a -o libScanApi.so -I ./ -L ./ -lfrt6 -I /usr/local/include/libusb-1.0/ -L /usr/local/lib/ -lusb-1.0
在這裡面,我生成了一個 libScanApi.so的庫,它依賴於靜態庫 libadd.a libade.a(靜態庫如若是自己編譯的,在編譯時候要加上-fPIC -shared),動態庫libfrt6.so和libusb-1.0.so。其中,-I後面接的是庫標頭檔案路徑, -L後面接的是庫路徑,如果還有更多的靜態庫或者動態庫需要被依賴,則在後面一次新增
關於靜態庫,似乎可用的資料就不是那麼多了
前不久遇到這樣的一個問題,我依賴於幾個.c檔案和兩個靜態庫的動態庫,需要提供一個靜態庫版本給客戶,當時感覺很鬱悶,因為兩個靜態庫我都是沒有原始碼的,網上找了許久也沒有找到自己想要的,後來求助一大神,終於完美解決。
我現在找不到那個網址了,不過還好儲存的還有截圖,可以參閱一下,同時也建議,如果要經常使用到靜態庫,可以先細讀一下ar的引數。
其實靜態庫也就相當於一個壓縮包,裡面存放的是一些.o檔案,把需要的.o放在一起打包,就生成了靜態庫。ar x A.a則正相反,是把生成A.a的.o檔案給解出來,這樣,即便是第三方庫我們也可以獲得其.o。而生成靜態庫的時候正是依賴於.o檔案,所以我們就可以依賴於多個靜態庫生成一個靜態庫了。
但是有的時候,貌似這樣還會錯誤,比如我上次用的是libusb-1.0.a的靜態庫,在解壓重新打包編譯之後,出現了這樣的問題
從錯誤中,可以很明顯的看到clock和pthread,很明顯,是缺少pthread庫和lrt(實時時鐘)庫的支援,於是在編譯時候在後面加上-lpthread 和-lrt就so easy 解決了
gcc -o tets testScanApi.c -L. -lFP_Ara -lpthread -lrt
相關推薦
linux下封裝函式庫——動態庫.so和靜態庫.a(程式碼實現及連結方式)
在linux環境下的連結庫分為靜態連結庫(.a庫)和動態連結庫(.so庫),其作用是把C程式編譯好做成一種可執行連結檔案,主程式檔案呼叫這些程式的函式介面是可以使用a庫或so庫,在主程式中只需要include含有庫中提供的函式介面宣告的標頭檔案即可。所以學會如何
linux 靜態庫動態庫封裝問題
在Linux下類庫主要有靜態庫和動態庫兩種庫,首先呢,就說說這兩種庫的差異: 靜態庫: 在程式連線的時候會自動的連線到程式裡, 所以一但編譯完成,靜態庫也就不需要了。靜態庫通常以.a結尾。
如何理解Linux下的動態庫概念,和靜態庫概念,通俗易懂的解釋如下:
動態庫和靜態庫都是一組函式集合,打包在一起供應用程式呼叫,區別是: 靜態庫名稱一般為xxx.a,在編譯時和應用程式連結在一起,這樣的應用程式佔用空間較大。 動態庫名稱一般為xxx.so,對於動態庫即可以在編譯時連結,也可以使用dlopen()/dlsy
Linux中的動態庫和靜態庫(.a.la.so.o)
Linux中的動態庫和靜態庫(.a/.la/.so/.o) 原文地址:https://www.cnblogs.com/findumars/p/5421910.html 在windows下,一般可以通過檔案的字尾名來識別檔案的型別。在Linux下大致上也是可以的。但是要明
linux 程式、動態庫、靜態庫內部新增版本號和編譯時間
給程式和庫新增版本號和庫,有利於維護和升級。 當然你可以在檔名上體現,比如有個程式叫 yun,檔名寫為 yun_1.0.2,但這個需要每次手動維護,而且不能100%確保當前程式就是那個版本。所以,把版本號體現在程式內部,是一個不錯的選擇。 --------------------------
linux下靜態庫動態庫的製作和使用
動態庫與靜態庫本質是二進位制的原始碼,只是人看不懂,對機器沒有影響。 靜態庫的製作和使用 命名規則: 名字一般分為三部分,開頭為“lib”,表示這是一個庫檔案,接下來是想取的名字,最後是字尾“.a”(windows下是lib)。例如:libhello.a 製作步驟: 1.原材料:
Linux系統的動態庫和靜態庫
靜態庫 靜態庫:一些公共程式碼是需要反覆使用,就把這些程式碼編譯為“庫”檔案;在連結步驟中,聯結器將從庫檔案取得所需的程式碼,複製到生成的可執行檔案中的這種庫。 程式編譯一般需經預處理、編譯、彙編和連結幾個步驟。靜態庫特點是可執行檔案中包含了庫程式碼的一份完整拷貝;缺點就是被多次
Ubuntu--(5)Linux下C++編譯生成自定義靜態庫/動態庫
編譯生成靜態庫: 1.編寫CPP檔案test.h #include <iostream> using namespace std; class ADD_SUB{ public
linux靜態庫 動態庫 去符號 符號恢復
前言 最近遇到了一題去除符號的題目,需要進行符號修復。為此學習了一波,順便補了補其它的一下知識。 準備知識 命名方式: 動態庫libxxx.so.major.minor .so .dll 靜態庫:libxxx.a
linux c/c++ 動態庫和靜態庫的生成與使用
二.介紹 從原始碼到可執行程式,通常要經過最重要的兩大步是:編譯,連結。編譯就是將原始檔生成中間檔案的過程,在linux下就是生成 .obj檔案。連結就是用連結器將,這些個中間檔案有序地”糅合“在一起,構成一個可執行檔案。通常,一個.c檔案或者.cpp原始檔編譯後,就會對應生成一個.obj檔案。
linux中建立自己的靜態庫 動態庫並使用
庫依賴: gcc connect.c –o connect –I /usr/include/mysql –L /usr/lib/mysql -lmysqlclient//-I是找到自己寫的標頭檔案所在的位置 -L是找到自己所寫的動態庫所在的位置,並且寫上函式名,靜態庫不用寫-L,只寫函式名//-I 是i 的大
Linux下靜態、動態庫(隱式、顯式呼叫)的建立和使用及區別
顯式呼叫的動態庫的建立與隱式呼叫相同。(隱式呼叫與靜態庫的使用方法一樣,不需要包含匯出函式的標頭檔案(顯式呼叫也不用包含標頭檔案),只需要在編譯可執行程式時指定庫檔案的路徑)顯式呼叫和隱式呼叫的區別在於:編譯可執行程式時需要指定庫檔案的搜尋路徑,而顯式呼叫編譯可執行程式時不用加上動態庫的搜尋路徑(因為已經在主
Linux下的動態庫和靜態庫
庫: 在c/c++裡,使用庫(library)的技術,可以將編譯好的符號提供給第三方使用。 1)共享庫(動態庫)share library 2) 靜態庫 static library 一:動態庫
linux兩種庫:動態庫和靜態庫(共享庫)說明
linux下有兩種庫:動態庫和靜態庫(共享庫) 二者的不同點在於程式碼被載入的時刻不同。 靜態庫的程式碼在編譯過程中已經被載入可執行程式,因此體積比較大。 動態庫(共享庫)的程式碼在可執行程式執行時才載入記憶體,在編譯過程中僅簡單的引用,因此程式碼體積比較
GCC實現多文件編譯,靜態庫,動態庫
blank () iba exp main.c run spa 文件夾 con 一 代碼 //add.h int add(int a, int b); //add.c int add(int a, int b) { r
靜態與動態庫文件
命令 ops 過去 編輯 shared 加載過程 二進制文件 函數 因此 在windows中靜態庫是以 .lib 為後綴的文件,共享庫是以 .dll 為後綴的文件。在linux中靜態庫是以 .a 為後綴的文件,共享庫是以 .so為後綴的文件。以linux下的靜態庫和動態庫為
linux和windows動態庫加載路徑區別
usr 路徑 推薦 div inux 但是 blog 區別 window # linux和windows動態庫加載路徑區別 ### 簡介------------------------------ linux加載動態庫的路徑是系統目錄/lib和/usr/lib。- win
linux建立靜動態庫
1.gcc編譯選項 -E : 預處理 .c -> .i -S : 編譯 .i /.c -> .s -c : 彙編 .s -> .o -g : 生成除錯資訊 -O : 優化級別 -O0 -O1 -O2 -O3 -Os -I : 包含一個頭檔案搜尋路徑 -I/home/li
再談Linux下的動態庫
為了解決上一篇的部落格《Linux下靜態庫、動態庫的建立和使用》最後留下的問題,今天總結一下Linux下動態庫 版本號的控制。 一、動態庫版本號的組成 對於上一篇部落格中提到的庫檔案libcurl.4.3.0,其中4代表主版本號,3代表次版本號,0代表發
linux下執行動態庫問題 cannot open shared object file: No such file or directory
如果動態庫不在同一級目錄下,則需要將以上檔案的目錄載入到動態庫搜尋路徑中,設定的方式有以下幾種: 一. 將動態庫路徑加入到LD_LIBRARY_PATH環境變數 1.在終端輸入:export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/XXX