1. 程式人生 > >Linux下的靜態庫與動態庫

Linux下的靜態庫與動態庫

在windows和Linux下都存在著大量的庫,庫是什麼呢?本質上來說,庫時一種可執行程式碼的二進位制形式,可以被作業系統載入記憶體執行。

庫有什麼用呢?

我們通常將一些公用函式寫成函式庫,所以庫是別人寫好的,現有的,成熟的,可以服用的程式碼,你可以使用但要必須得遵守許可協議。在我們現實開發過程中,不可能每一份程式碼都從頭編寫,當我們擁有庫時,我們就可以直接將我們所需要的檔案連結到我們的程式中。可以為我們節省大量的時間,提高開發效率。所以,哭的存在意義是不可藐視的。

Linux下的庫

Linux下庫分為兩種,靜態庫和動態庫。

區別

這兩種庫相同點是兩種庫都是由.o檔案生成的,下邊討論一下它們的不同點:

  • 靜態庫
    靜態庫檔名的命名方式是“libxxx.a”,庫名前加”lib”,字尾用”.a”,“xxx”為靜態庫名。
    連結時間: 靜態庫的程式碼是在編譯過程中被載入程式中。
    連結方式:靜態庫的連結是將整個函式庫的所有資料都整合進了目的碼。這樣做優點是在編譯後的執行程式不在需要外部的函式庫支援,因為所使用的函式都已經被編進去了。缺點是,如果所使用的靜態庫發生更新改變,你的程式必須重新編譯。

  • 動態庫
    動態庫的命名方式與靜態庫類似,字首相同,為“lib”,字尾變為“.so”。所以為“libmytime.so”
    連結時間:動態庫在編譯的時候並沒有被編譯進目的碼,而是當你的程式執行到相關函式時才呼叫該函式庫裡的相應函式。這樣做缺點是因為函式庫並沒有整合程序序,所以程式的執行環境必須提供相應的庫。優點是動態庫的改變並不影響你的程式,所以動態函式庫升級比較方便。

它們兩個還有很明顯的不同點:當同一個程式分別使用靜態庫,動態庫兩種方式生成兩個可執行檔案時,靜態連結所生成的檔案所佔用的記憶體要遠遠大於動態連結所生成的檔案。(因為靜態連結是在編譯時將所有的函式都編譯進了程式。而動態連結是在執行是才呼叫庫裡相應函式)

兩種庫的應用例項

問題描述:現假設我們現在需要一個函式庫,庫裡面有一個需要可以列印時間的函式,分別以靜態庫,動態庫的方式實現。
準備三個檔案 time.c time.h test.c。

//time.h  函式庫的標頭檔案
#ifndef __TIME_H_
#define __TIME_H_

#include<stdio.h>
void time(); #endif //__TIME_H_
//time.c函式庫的源程式,包含時間列印函式
#include"time.h"

void time()
{
    printf("today is 2017:2:17\n");
}
//test.c  測試函式,呼叫了時間列印函式time
#include"time.h"

int main()
{
    time();
    return 0;
}

上面提到過,無論靜態庫還是動態庫都是由.o檔案生成的,所以將time.c編譯成time.o。

gcc -o time.c

這裡寫圖片描述

在下面生成靜態庫,動態庫檔案的時候,你可能會出現這樣的錯誤:

/usr/bin/ld: cannot find lc

執行下面命令安裝glibc-static即可:(在root許可權下)

yum install glibc-static

靜態庫

由.o檔案生成靜態庫檔案

設靜態庫名稱為mytime,所以靜態庫的檔名就為libmytime.a

ar cr libmytime.a time.o

這裡寫圖片描述

靜態庫的使用

執行下面命令進行靜態連結,生成可執行程式。

gcc -o test test.c -static -lmytime -L.
  • -static :表示程式的靜態連結
  • -lmytime:連結靜態庫mytime
  • -L. :連結時需指明靜態庫所存在的路徑,‘.’表示當前路徑

這裡寫圖片描述

執行test

./test

這裡寫圖片描述

現將當前目錄下的靜態庫檔案libmytime.a刪除,再次執行test。我們會發現程式依然執行成功。

這裡寫圖片描述

這是因為靜態庫連結是在程式編譯時就將所有程式碼整合到了程式中,編譯後的可執行程式不再需要外部的函式庫支援。

動態庫

由.o檔案生成動態庫

設動態庫名為mytime,則動態庫的檔名就為libmytime.so

gcc -shared -fPCI -o libmytime.so time.so

這裡寫圖片描述

動態庫的使用

執行下面命令進行動態連結,生成可執行程式。

gcc -o test test.c -lmytime -L.

這裡寫圖片描述

執行test。

./test

這裡寫圖片描述

我們會發現程式報錯了,錯誤是沒有找到動態庫libmytime.so 。因為進行動態連結時,程式並不會在當前目錄中尋找動態庫,而是會在/usr/lib目錄下尋找,所以我們將動態庫libmytime.so移動到/usr/lib下就可以了。(在root許可權下)

mv libmytime.so /usr/lib

再次執行程式,程式執行成功。

這裡寫圖片描述

比較兩個可執行檔案的大小,我們會發現靜態連結生成的可執行檔案要遠遠大於動態連結生成的可執行檔案。

  • 靜態連結
    這裡寫圖片描述

  • 動態連結
    這裡寫圖片描述

相關推薦

Linux靜態動態

Linux 靜態庫 動態庫 靜態庫 先說說我們為什麽需要庫?當有些代碼我們大量會在程序中使用比如(scanf,printf等)這些函數我們需要在程序中頻繁使用,於是我們就把這些代碼編譯為庫文件,在需要使用時我們直接鏈接即可。 定義: ?程序在編譯時把靜態庫的代碼鏈接到可執行程序中,在代碼運行時不再

Linux靜態動態(.a、.so)

ref:http://niefei.blog.ccidnet.com/blog/ccid/do_showone/tid_42855.html 1. 介紹   使用GNU的工具我們如何在Linux下建立自己的程式函式庫?一個“程式函式庫”簡單的說就是一個檔案包含了一些編譯好的程式碼和資料,這些編譯好的程式碼和資

Linux靜態動態

庫 在windows和Linux下都存在著大量的庫,庫是什麼呢?本質上來說,庫時一種可執行程式碼的二進位制形式,可以被作業系統載入記憶體執行。 庫有什麼用呢? 我們通常將一些公用函式寫成函式庫,所以庫是別人寫好的,現有的,成熟的,可以服用的程式碼,你可

深入探討Linux靜態動態的詳解(轉)

share 分享 命名 one .com 過程 程序 簡單介紹 mage 2.生成動態庫並使用 linux下編譯時通過 -shared 參數可以生成動態庫(.so)文件,如下 庫從本質上來說是一種可執行代碼的二進制格式,可以被載入內存中執行。庫分靜態庫和動態庫兩種。

【領卓教育】Linux--靜態動態(共享) 區別、製作和使用

1.概念和區別      靜態庫 :(1)libxxx.a ,程式在編譯時,將庫編譯 進可執行程式中!                     &nbs

LINUX靜態動態符號衝突問題分析解決

1. 問題重現模型 為了重現問題並去掉無關干擾細節,我們將構建一個最簡單的可執行模組和依賴模組的關係鏈,程式依賴模型如下: 1.1 解釋 (1)有一個名為RTSP的第三方庫提供了公共介面RTSP_OPEN,RTSP可以編譯為靜態庫libRTSP_ST

linuxg++ 編譯時動態靜態的連結和標頭檔案問題

原來編譯的時候都是用的很隨意,沒用系統的總結一下,這幾天在編譯的時候遇到一些下問題,於是就總結一下,省得過幾天又給忘了。 1.動態庫和靜態庫簡介 靜態庫在程式連結的時候會自動的連結到程式裡,所以一旦編譯完成,靜態庫就不需要了,靜態庫以.a結尾。  動態庫在編譯時不會被連線到目的碼中,而是在程式執行

Linux用Makefile製作動態靜態並編譯生成可執行程式

Makefile 一個工程中的原始檔不計其數,其按型別、功能、模組分別放在若干個目錄中,makefile定義了一系列的規則來指定,哪些檔案需要先編譯,哪些檔案需要後編譯,哪些檔案需要重新

靜態動態的簡單說明

外部程序 endif ldconfig 開始 director 有時 鏈接 現在 con   一.靜態庫和動態庫的簡單介紹   程序設計的模塊化是人們一直在追求的目標,因為當一個系統十分復雜的時候,將系統模塊化既可以並行開發,又可以增強程序的可用性,降低程序間的耦合度。在一

VS2015靜態動態的使用

VS2015靜態庫與動態庫的使用 靜態庫 靜態庫建立(略),往往我們使用第三方的比較常見,如果要自己團隊間建立使用也很簡單; 標頭檔案的載入:  方式一: (1)將靜態庫給出的標頭檔案拷貝到專案目錄下(*.vcxproj所在的目錄); (2

解決 openssl 在Linux 預設不生成動態的問題

在Linux下利用原始碼安裝 OpenSSL 通常預設不會生成動態庫,解決辦法: 在config 加上 shared 選項 具體指令 ./config shared configure 制定生成靜態庫辦法: --enable-shared=no --enable-static

CMake的hello world(三) 靜態動態構建

本系列都是學習<CMake實踐>這本書,書下載連結 https://download.csdn.net/download/hjxu2016/10741464 這次任務是建立一個靜態庫和動態庫, 提供helloFunc函式供其他程式程式設計使用,HelloFunc向終端輸出 H

HelloWorld CMake CMake中構建靜態動態及其使用

繼續完善Hello World,建立它的共享庫, 包括靜態庫和動態庫。   本節的任務: 1,建立一個靜態庫和動態庫,提供HelloFunc函式供其他程式程式設計使用,HelloFunc 向終端輸出Hello World字串。 2,安裝標頭檔案與

C++靜態動態

name mangling可以通過extern "C"解決。C++有個特定的關鍵字用來宣告採用C binding的函式:extern "C" 。用 extern "C"宣告的函式將使用函式名作符號名,就像C函式一樣。因此,只有非成員函式才能被宣告為extern "C",並且不能被過載。儘管限制多多,exter

CMake中構建靜態動態及其使用(CMakeLists的一些解釋)

本節的任務: 1,建立一個靜態庫和動態庫,提供HelloFunc函式供其他程式程式設計使用,HelloFunc 向終端輸出Hello World字串。 2,安裝標頭檔案與共享庫。 3, 編寫一個程式使用建立的共享庫(靜態庫和動態庫)。 cd /home/ccj/

《CMake實踐》筆記三:構建靜態動態 及 如何使用外部共享和標頭檔案

五、靜態庫與動態庫構建 讀者雲,太能羅唆了,一個Hello World就折騰了兩個大節。OK,從本節開始,我們不再折騰Hello World了,我們來折騰Hello World的共享庫。 本節的任務: 1、建立一個靜態庫和動態庫,提供HelloFunc函式供

linux建立,使用動態

1. 現在要生成libmydll.so的庫檔案,標頭檔案如下 #ifndef  _MYDLL_H #define  _MYDLL_H #include "stdio.h" #ifdef WIN32     #ifdef MYDLL_EXPORTS         #defi

cmake學習(一)靜態動態構建

因為預設規則是不能有相同名字的共享庫與靜態庫,所以當生成靜態庫的時候(so字尾),共享庫會被刪除,因為只能允許一個名字存在,相同名字的會被替代(hello),所以需要通過SET_TARGET_PROPERTIES()來解決這個問題,例子:

編譯小結(7)Automake編譯靜態動態

  具體記錄下,如何用Automake編譯靜態庫(.a)與動態庫(.so)的流程.   步驟其實都是一樣的,只有configure.in 與 Makefile.am 有區別。 一。靜態庫(.a)

C++靜態動態詳解使用

這次分享的宗旨是——讓大家學會建立與使用靜態庫、動態庫,知道靜態庫與動態庫的區別,知道使用的時候如何選擇。這裡不深入介紹靜態庫、動態庫的底層格式,記憶體佈局等,有興趣的同學,推薦一本書《程式設計師的自我修養——連結、裝載與庫》。 什麼是庫 庫是寫好的現有的,成熟的,可以複用的程式碼。現實中每個程式都要依