1. 程式人生 > >linux 靜態庫動態庫封裝問題

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]# vi zyx.c
                [[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
                [
[email protected]
Source]# ./zyx

    動態庫:

        通過一個例子來介紹如何生成一個動態庫。這裡有一個頭檔案: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