新聞中心
隨著計(jì)算機(jī)領(lǐng)域的快速發(fā)展和應(yīng)用程序的增多,動(dòng)態(tài)庫(kù)和靜態(tài)庫(kù)的應(yīng)用也越來(lái)越廣泛,特別是在Linux系統(tǒng)中,由于其開(kāi)放的特性和強(qiáng)大的定制性,更是成為了應(yīng)用程序開(kāi)發(fā)的重要基礎(chǔ)。那么,什么是Linux動(dòng)態(tài)庫(kù)和靜態(tài)庫(kù)?它們有什么區(qū)別?在軟件開(kāi)發(fā)中應(yīng)該如何合理選擇和應(yīng)用呢?本文就來(lái)詳細(xì)介紹一下,希望能夠?yàn)樽x者提供有幫助的知識(shí)。

一、什么是Linux動(dòng)態(tài)庫(kù)和靜態(tài)庫(kù)?
1. 動(dòng)態(tài)庫(kù)
動(dòng)態(tài)庫(kù)是指在程序運(yùn)行時(shí)才會(huì)被加載到內(nèi)存中執(zhí)行的庫(kù)。它通常以.so或者.dll等后綴名為標(biāo)識(shí),并可被不同的程序共享使用。當(dāng)程序初始化時(shí),動(dòng)態(tài)庫(kù)并沒(méi)有被加載,直到程序運(yùn)行時(shí)程序需要調(diào)用動(dòng)態(tài)庫(kù)中的某個(gè)函數(shù)時(shí),動(dòng)態(tài)庫(kù)才會(huì)被動(dòng)態(tài)地加載到內(nèi)存中,從而被程序調(diào)用。這種方式可以大大減小程序的運(yùn)行文件大小,節(jié)省系統(tǒng)內(nèi)存資源,提高代碼的重用性,并更加方便程序的更新和維護(hù)。
2. 靜態(tài)庫(kù)
靜態(tài)庫(kù)是指將所有的程序代碼和函數(shù)庫(kù)在編譯時(shí)就打包到了可執(zhí)行程序中的一種庫(kù)。它通常以.a、.lib等后綴名為標(biāo)識(shí),并不可被不同的程序共享使用。靜態(tài)庫(kù)雖然比較占用存儲(chǔ)空間,但是其執(zhí)行速度快,能夠?qū)⒊绦虻囊蕾囮P(guān)系全部展開(kāi),避免程序的一些不必要的依賴問(wèn)題,使得程序的可靠性更高。
二、Linux動(dòng)態(tài)庫(kù)和靜態(tài)庫(kù)的區(qū)別
1. 存儲(chǔ)方式
動(dòng)態(tài)庫(kù)和靜態(tài)庫(kù)的存儲(chǔ)方式不同。動(dòng)態(tài)庫(kù)所包含的函數(shù)代碼并不被直接加載到可執(zhí)行程序中,而是在程序運(yùn)行時(shí)才被載入到內(nèi)存中。而靜態(tài)庫(kù)則是將所有的庫(kù)文件在編譯時(shí)就已經(jīng)打包到了可執(zhí)行程序中。
2. 程序的運(yùn)行特性
動(dòng)態(tài)庫(kù)和靜態(tài)庫(kù)對(duì)程序的運(yùn)行特性也有影響。動(dòng)態(tài)庫(kù)的優(yōu)勢(shì)在于占用內(nèi)存資源小、可重用性高,及時(shí)更新等,但是動(dòng)態(tài)庫(kù)的載入和卸載會(huì)對(duì)程序的運(yùn)行速度造成一定的影響。而靜態(tài)庫(kù)的優(yōu)勢(shì)在于單一性強(qiáng),依賴性小,且程序的執(zhí)行效率高,但是占用內(nèi)存大,更新維護(hù)麻煩。
3. 應(yīng)用場(chǎng)景
在實(shí)際應(yīng)用場(chǎng)景中,動(dòng)態(tài)庫(kù)和靜態(tài)庫(kù)應(yīng)用的場(chǎng)合不同。動(dòng)態(tài)庫(kù)適用于需要運(yùn)行效率高,占用內(nèi)存資源小,更新和維護(hù)方便等應(yīng)用場(chǎng)景,亦適用于相同的函數(shù)和庫(kù)被多個(gè)程序共享使用。而靜態(tài)庫(kù)適用于需要較高的安全性和穩(wěn)定性等應(yīng)用場(chǎng)合,且對(duì)程序的執(zhí)行速度要求較高的情況下使用。
三、合理選擇和應(yīng)用
在軟件開(kāi)發(fā)中,如何合理地選擇和應(yīng)用動(dòng)態(tài)庫(kù)和靜態(tài)庫(kù)呢?對(duì)此,本文向大家介紹幾點(diǎn)建議:
1. 根據(jù)需求選擇
選擇動(dòng)態(tài)庫(kù)還是靜態(tài)庫(kù),應(yīng)該根據(jù)需求來(lái)選擇,即要看開(kāi)發(fā)的程序所需要的特征是什么,如穩(wěn)定性、可維護(hù)性、執(zhí)行速度等方面,選擇合適的庫(kù)進(jìn)行開(kāi)發(fā)。
2. 盡量少用靜態(tài)庫(kù)
雖然靜態(tài)庫(kù)具有高效性和可靠性高等優(yōu)點(diǎn),但是由于靜態(tài)庫(kù)的更新、維護(hù)和管理都比較麻煩,同時(shí)占用內(nèi)存資源也比較大,因此在實(shí)際開(kāi)發(fā)中應(yīng)該盡量少用靜態(tài)庫(kù)。
3. 動(dòng)態(tài)庫(kù)可用于插件開(kāi)發(fā)
插件開(kāi)發(fā)是動(dòng)態(tài)庫(kù)的典型應(yīng)用場(chǎng)景,相應(yīng)的插件可以動(dòng)態(tài)的加載到程序中,從而實(shí)現(xiàn)靈活的擴(kuò)展和功能擴(kuò)充。
4. 重復(fù)代碼要用動(dòng)態(tài)庫(kù)
當(dāng)開(kāi)發(fā)中有多個(gè)應(yīng)用程序需要使用到相似甚至相同的代碼段時(shí),為了提高程序的重用性和可維護(hù)性,建議采用動(dòng)態(tài)庫(kù)來(lái)實(shí)現(xiàn)重復(fù)代碼的共享。
結(jié)語(yǔ):
本文對(duì)于Linux動(dòng)態(tài)庫(kù)和靜態(tài)庫(kù)的基本概念、區(qū)別和應(yīng)用進(jìn)行了比較詳細(xì)的介紹,相信對(duì)讀者有所幫助。在實(shí)際的軟件開(kāi)發(fā)中,根據(jù)實(shí)際情況選擇適當(dāng)?shù)膸?kù)進(jìn)行開(kāi)發(fā)是非常重要的,本文也為大家提供了一些實(shí)用的建議和參考。
成都網(wǎng)站建設(shè)公司-創(chuàng)新互聯(lián)為您提供網(wǎng)站建設(shè)、網(wǎng)站制作、網(wǎng)頁(yè)設(shè)計(jì)及定制高端網(wǎng)站建設(shè)服務(wù)!
關(guān)于動(dòng)態(tài)庫(kù) 靜態(tài)庫(kù) 區(qū)別與使用 路徑查找等
一、引言
我晌段稿們通常把一些公用函數(shù)制作成函數(shù)庫(kù),供其它程序使用。
函數(shù)庫(kù)分為靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)兩種。
通常情況下,對(duì)函數(shù)庫(kù)的鏈接是放在編譯時(shí)期(compile time)完成的。所有相關(guān)的對(duì)象文件(object file)與牽涉到的函數(shù)庫(kù)(library)被鏈接合成一個(gè)可執(zhí)行文件(executable file)。程序在運(yùn)行時(shí),與函數(shù)庫(kù)再無(wú)瓜葛,因?yàn)樗行枰暮瘮?shù)已拷貝到相應(yīng)目錄下下。所以這些函數(shù)庫(kù)被成為靜態(tài)庫(kù)(static libaray),通常文件名為“l(fā)ibxxx.a”的形式。
其實(shí),我們也可以把對(duì)一些庫(kù)函數(shù)的鏈接載入推遲到程序運(yùn)行的時(shí)期(runtime)。這就是動(dòng)態(tài)鏈接庫(kù)(dynamic link library)技術(shù)。
二、兩者區(qū)別:
a,靜態(tài)庫(kù)的使用需要:
1 包含一個(gè)對(duì)應(yīng)的頭文件告知編譯器lib文件里面的具體內(nèi)容
2 設(shè)置lib文件允許編譯器去查找已經(jīng)編譯好的二進(jìn)制代碼
b,動(dòng)態(tài)庫(kù)的使用:
程序運(yùn)行時(shí)需要加載動(dòng)態(tài)庫(kù),對(duì)動(dòng)態(tài)庫(kù)有依賴性,需要手動(dòng)加入動(dòng)態(tài)庫(kù)
c,依賴性:
靜態(tài)鏈接表示靜態(tài)性,在編譯鏈接之后, lib庫(kù)中需要的資源已經(jīng)在可執(zhí)行程序中了, 也就是靜態(tài)存在,沒(méi)有依賴性了
動(dòng)態(tài),就是實(shí)時(shí)性,在運(yùn)行的時(shí)候載入需要的資源,那么必須在運(yùn)行的時(shí)候提供 需要的 動(dòng)態(tài)庫(kù),有依賴性, 運(yùn)行時(shí)候沒(méi)有找到庫(kù)就不能運(yùn)行了
d,區(qū)別:
簡(jiǎn)單講,靜態(tài)庫(kù)就是直接將需要的代碼連接進(jìn)可執(zhí)行程序;動(dòng)態(tài)庫(kù)就是在需要調(diào)用其中的函數(shù)時(shí),根據(jù)函數(shù)映射表找到該函數(shù)然后調(diào)入堆棧執(zhí)行。
做成靜態(tài)庫(kù)可執(zhí)行文件本身比較大,但不必附帶動(dòng)態(tài)庫(kù)
做成動(dòng)態(tài)庫(kù)可執(zhí)行文件本身比較小,但需要附帶動(dòng)態(tài)庫(kù)
鏈接靜態(tài)庫(kù),編譯的可執(zhí)行文件比較大,當(dāng)然可以用strip命令精簡(jiǎn)一下(如:strip libtest.a),但還是要比鏈接動(dòng)態(tài)庫(kù)的可執(zhí)行文件大。程序運(yùn)行時(shí)間燃灶速度稍微快一點(diǎn)。
靜態(tài)庫(kù)是程序運(yùn)行的時(shí)候已經(jīng)調(diào)入內(nèi)存,不管有沒(méi)有調(diào)用,都會(huì)在內(nèi)存里頭。靜態(tài)庫(kù)在程序編譯時(shí)會(huì)被連接到目標(biāo)代碼中,程序運(yùn)行時(shí)將不再需要該靜態(tài)庫(kù)。
其在編譯程序時(shí)若鏈接,程序運(yùn)行時(shí)會(huì)在系統(tǒng)指定的路徑下搜索,然后導(dǎo)入內(nèi)存,程序一般執(zhí)行時(shí)間稍微長(zhǎng)一點(diǎn),但編譯的可執(zhí)行文件比較小;動(dòng)態(tài)庫(kù)是程序運(yùn)行的時(shí)候需要調(diào)用的時(shí)候才裝入內(nèi)存,不需要的時(shí)候是不會(huì)裝入內(nèi)存的。
動(dòng)態(tài)庫(kù)在程序編譯時(shí)并不會(huì)被連接到目標(biāo)代碼中,而是在程序運(yùn)行是才被載入,因此在程序運(yùn)行時(shí)還需要?jiǎng)討B(tài)庫(kù)存在。
三、動(dòng)態(tài)鏈接庫(kù)的特點(diǎn)與優(yōu)勢(shì)
首先讓我們來(lái)看一下,把庫(kù)函數(shù)推遲到程序運(yùn)行時(shí)期載入的好處:
1. 可以實(shí)現(xiàn)進(jìn)程之間的資源共享。
什么概念呢?就是說(shuō),某個(gè)程序的在運(yùn)行中要調(diào)用某個(gè)動(dòng)態(tài)鏈接庫(kù)函數(shù)的時(shí)候,操作系統(tǒng)首先會(huì)查看所有正在運(yùn)行的程序,看在內(nèi)存里宴孝是否已有此庫(kù)函數(shù)的拷貝了。如果有,則讓其共享那一個(gè)拷貝;只有沒(méi)有才鏈接載入。這樣的模式雖然會(huì)帶來(lái)一些“動(dòng)態(tài)鏈接”額外的開(kāi)銷,卻大大的節(jié)省了系統(tǒng)的內(nèi)存資源。C的標(biāo)準(zhǔn)庫(kù)就是動(dòng)態(tài)鏈接庫(kù),也就是說(shuō)系統(tǒng)中所有運(yùn)行的程序共享著同一個(gè)C標(biāo)準(zhǔn)庫(kù)的代碼段。
2. 將一些程序升級(jí)變得簡(jiǎn)單。用戶只需要升級(jí)動(dòng)態(tài)鏈接庫(kù),而無(wú)需重新編譯鏈接其他原有的代碼就可以完成整個(gè)程序的升級(jí)。Windows 就是一個(gè)很好的例子。
3. 甚至可以真正坐到鏈接載入完全由程序員在程序代碼中控制。
程序員在編寫(xiě)程序的時(shí)候,可以明確的指明什么時(shí)候或者什么情況下,鏈接載入哪個(gè)動(dòng)態(tài)鏈接庫(kù)函數(shù)。你可以有一個(gè)相當(dāng)大的軟件,但每次運(yùn)行的時(shí)候,由于不同的操作需求,只有一小部分程序被載入內(nèi)存。所有的函數(shù)本著“有需求才調(diào)入”的原則,于是大大節(jié)省了系統(tǒng)資源。比如現(xiàn)在的軟件通常都能打開(kāi)若干種不同類型的文件,這些讀寫(xiě)操作通常都用動(dòng)態(tài)鏈接庫(kù)來(lái)實(shí)現(xiàn)。在一次運(yùn)行當(dāng)中,一般只有一種類型的文件將會(huì)被打開(kāi)。所以直到程序知道文件的類型以后再載入相應(yīng)的讀寫(xiě)函數(shù),而不是一開(kāi)始就將所有的讀寫(xiě)函數(shù)都載入,然后才發(fā)覺(jué)在整個(gè)程序中根本沒(méi)有用到它們。
靜態(tài)庫(kù):在編譯的時(shí)候加載生成目標(biāo)文件,在運(yùn)行時(shí)不用加載庫(kù),在運(yùn)行時(shí)對(duì)庫(kù)沒(méi)有依賴性。
動(dòng)態(tài)庫(kù):在目標(biāo)文件運(yùn)行時(shí)加載,手動(dòng)加載,且對(duì)庫(kù)有依賴性。
具體在開(kāi)發(fā)中用到哪種庫(kù),我覺(jué)得還是根據(jù)實(shí)際的內(nèi)存大小,ROM大小,運(yùn)行的速度等綜合考慮。
關(guān)于c/c++靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)的區(qū)別
靜態(tài)庫(kù)
之所以成為【靜態(tài)庫(kù)】,是因?yàn)樵阪溄与A段,會(huì)將匯編生成的目標(biāo)文件.o與引用到的庫(kù)一起鏈接打包到可執(zhí)行文件中。因此對(duì)應(yīng)的鏈接方式稱為靜態(tài)鏈接。
試想一下,靜態(tài)庫(kù)與匯編生成的目標(biāo)文件一起鏈接為可執(zhí)行文件,那么靜態(tài)庫(kù)必定跟.o文件格式相似。其實(shí)一個(gè)靜態(tài)庫(kù)可以簡(jiǎn)單看成是一組目標(biāo)文件(.o/.obj文件)的,即很多目標(biāo)文件經(jīng)過(guò)壓縮打包后形成的一個(gè)文件。靜態(tài)庫(kù)特點(diǎn)總結(jié):
l 靜態(tài)庫(kù)對(duì)函數(shù)庫(kù)的鏈接是放在編譯時(shí)期完成的。
l 程序在運(yùn)行時(shí)與函數(shù)庫(kù)再無(wú)瓜葛,移植方便。
l 浪費(fèi)空間和資源,因?yàn)樗邢嚓P(guān)的目標(biāo)文件與牽涉到的函數(shù)庫(kù)被鏈接合成一個(gè)可執(zhí)行文件。
下面編寫(xiě)一些簡(jiǎn)單的四則運(yùn)算C++類,將其編譯孫陵敬成靜態(tài)庫(kù)給他人用,頭文件如下所示:
StaticMath.h頭文件
#pragma once
class StaticMath
{
public:
StaticMath(void);
~StaticMath(void);
static double add(double a, double b);//加法
static double sub(double a, double b);//減法
static double mul(double a, double b);//乘法
static double div(double a, double b);//除法
void print();
};
Linux下使用ar工具、Windows下vs使用lib.exe,將目標(biāo)文件壓縮到一起,并且對(duì)其進(jìn)行編號(hào)和索引,以便于查找和檢索。一般創(chuàng)建靜態(tài)庫(kù)的步驟如圖所示:
圖:創(chuàng)建靜態(tài)庫(kù)過(guò)程
Linux下創(chuàng)建與使用靜態(tài)庫(kù)
Linux靜態(tài)庫(kù)命名規(guī)則
Linux靜態(tài)庫(kù)命名規(guī)則慎范,必須是”lib.a”:lib為前綴,中間是靜態(tài)庫(kù)名,擴(kuò)展名為.a。
創(chuàng)建靜態(tài)庫(kù)(.a)
通過(guò)上面的流程可以知道,Linux創(chuàng)建靜態(tài)庫(kù)過(guò)程如下:
l 首先,將代碼文件編譯成目標(biāo)文件.o(StaticMath.o)
g++ -c StaticMath.cpp
注意帶參數(shù)-c,否則直接編譯為可執(zhí)行文件
l 然后,通過(guò)ar工具將目標(biāo)文件打包成.a靜態(tài)庫(kù)文件
ar -crv libstaticmath.a StaticMath.o
生成靜態(tài)庫(kù)libstaticmath.a。
大一點(diǎn)的項(xiàng)目會(huì)編寫(xiě)makefile文件(CMake等等工程管理工具)來(lái)生成靜態(tài)庫(kù),輸入多個(gè)命令太麻煩了。
使用靜態(tài)庫(kù)
編寫(xiě)使用上面創(chuàng)建的靜態(tài)庫(kù)的測(cè)試代碼:
測(cè)試代碼:
#include “StaticMath.h”
#include
using namespace std;
int main(int argc, char* argv)
{
double a = 10;
double b = 2;
cout
using namespace std;
int main(int argc, char* argv)
{
double a = 10;
double b = 2;
cout
using namespace std;
int _tmain(int argc, _TCHAR* argv)
{
double a = 10;
double b = 2;
cout ,提供了下面幾個(gè)接口:
l void * dlopen( const char * pathname, int mode ):函數(shù)以指定模式打開(kāi)指定的動(dòng)態(tài)連接庫(kù)文件,并返回一個(gè)句柄給調(diào)用進(jìn)程。
l void* dlsym(void* handle,const char* symbol):dlsym根據(jù)動(dòng)態(tài)鏈接庫(kù)操作句柄(pHandle)與符號(hào)(symbol),返回符號(hào)對(duì)應(yīng)的地址。使用這個(gè)函數(shù)不但可以獲取函數(shù)地址,也可以獲取變量地址。
l int dlclose (void *handle):dlclose用于關(guān)閉指定句柄的動(dòng)態(tài)鏈接庫(kù),只有當(dāng)此動(dòng)態(tài)鏈接庫(kù)的使用計(jì)數(shù)為0時(shí),才會(huì)真正被系統(tǒng)卸載。
l const char *dlerror(void):當(dāng)動(dòng)態(tài)鏈接庫(kù)操作函數(shù)執(zhí)行失敗時(shí),dlerror可以返回出錯(cuò)信息,返回值為NULL時(shí)表示操作函數(shù)執(zhí)行成功。
在Windows下顯式調(diào)用動(dòng)態(tài)庫(kù)
應(yīng)用程序必須進(jìn)行函數(shù)調(diào)用以在運(yùn)行時(shí)顯式加載 DLL。為顯式鏈接到 DLL,應(yīng)用程序必須:
l 調(diào)用 LoadLibrary(或相似的函數(shù))以加載 DLL 和獲取模塊句柄。
l 調(diào)用 GetProcAddress,以獲取指向應(yīng)用程序要調(diào)用的每個(gè)導(dǎo)出函數(shù)的函數(shù)指針。由于應(yīng)用程序是通過(guò)指針調(diào)用 DLL 的函數(shù),編譯器不生成外部引用,故無(wú)需與導(dǎo)入庫(kù)鏈接。
l 使用完 DLL 后調(diào)用 FreeLibrary。
顯式調(diào)用C++動(dòng)態(tài)庫(kù)注意點(diǎn)
對(duì)C++來(lái)說(shuō),情況稍微復(fù)雜。顯式加載一個(gè)C++動(dòng)態(tài)庫(kù)的困難一部分是因?yàn)镃++的name
mangling;另一部分是因?yàn)闆](méi)有提供一個(gè)合適的API來(lái)裝載類,在C++中,您可能要用到庫(kù)中的一個(gè)類,而這需要?jiǎng)?chuàng)建該類的一個(gè)實(shí)例,這不容易做到。
name mangling可以通過(guò)extern “C”解決。C++有個(gè)特定的關(guān)鍵字用來(lái)聲明采用C
binding的函數(shù):extern “C” 。用 extern “C”聲明的函數(shù)將使用函數(shù)名作符號(hào)名,就像C函數(shù)一樣。因此,只有非成員函數(shù)才能被聲明為extern
“C”,并且不能被重載。盡管限制多多,extern “C”函數(shù)還是非常有用,因?yàn)樗鼈兛梢韵驝函數(shù)一樣被dlopen動(dòng)態(tài)加載。冠以extern
linux動(dòng)態(tài)庫(kù)與靜態(tài)庫(kù)的區(qū)別的介紹就聊到這里吧,感謝你花時(shí)間閱讀本站內(nèi)容,更多關(guān)于linux動(dòng)態(tài)庫(kù)與靜態(tài)庫(kù)的區(qū)別,Linux動(dòng)態(tài)庫(kù)和靜態(tài)庫(kù)有什么區(qū)別,關(guān)于動(dòng)態(tài)庫(kù) 靜態(tài)庫(kù) 區(qū)別與使用 路徑查找等,關(guān)于c/c++靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)的區(qū)別的信息別忘了在本站進(jìn)行查找喔。
創(chuàng)新互聯(lián)-老牌IDC、云計(jì)算及IT信息化服務(wù)領(lǐng)域的服務(wù)供應(yīng)商,業(yè)務(wù)涵蓋IDC(互聯(lián)網(wǎng)數(shù)據(jù)中心)服務(wù)、云計(jì)算服務(wù)、IT信息化、AI算力租賃平臺(tái)(智算云),軟件開(kāi)發(fā),網(wǎng)站建設(shè),咨詢熱線:028-86922220
文章名稱:Linux動(dòng)態(tài)庫(kù)和靜態(tài)庫(kù)有什么區(qū)別(linux動(dòng)態(tài)庫(kù)與靜態(tài)庫(kù)的區(qū)別)
網(wǎng)頁(yè)URL:http://www.5511xx.com/article/dhdssog.html


咨詢
建站咨詢
