日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux系统中 库分为静态库和,你知道linux 静态库和共享库?

發布時間:2025/3/21 linux 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux系统中 库分为静态库和,你知道linux 静态库和共享库? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1、靜態庫和共享庫

靜態庫和共享庫(動態庫),二者的不同點在于代碼被載入的時刻不同。

靜態庫的代碼在編譯過程中已經被載入可執行程序,因此體積較大。

共享庫的代碼是在可執行程序運行時才載入內存的,在編譯過程中僅簡單的引用,因此代碼體積較小。

靜態鏈接庫和動態鏈接庫的區別在于,主程序在運行前,靜態鏈接庫的鏈接固定寫入在程序中,而動態鏈接庫則是在每次程序運行再加載鏈接。

2、庫存在的意義

庫是別人寫好的現有的,成熟的,可以復用的代碼,你可以使用但要記得遵守許可協議。

現實中每個程序都要依賴很多基礎的底層庫,不可能每個人的代碼都從零開始,因此庫的存在意義非同尋常。

共享庫的好處是,不同的應用程序如果調用相同的庫,那么在內存里只需要有一份該共享庫的實例。

3.靜態庫

Step 1.由源文件編譯生成一堆.o,每個.o里都包含這個編譯單元的符號表

Step 2.ar命令將很多.o轉換成.a,成為靜態庫

靜態鏈接庫 libcool.a 遵從 GNU/Linux 規定的靜態鏈接庫命名規范,必須是”libyour_library_name.a”

動態庫的后綴是.so,它由gcc加特定參數編譯產生。

4、動態庫

在 GNU/Linux 中動態鏈接文件,必需通過鏈接器 ld 生成。假設我們有 hot.c other.c 等文件要生成動態鏈接庫 libhot.so 。首先使用如下指令得到相應的 object 文件 hot.o 和 other.o

gcc -fPIC -c hot.c

gcc -fPIC -c other.c

參數 -fPIC 指定生成的 object 文件為位置無關代碼(position-independence code),只有 PIC 可以被用作生成動態鏈接庫。然后使用如下指令得到動態庫:

ld -Bshared -o libhot.so hot.o other.o

或者可以使用編譯器的ld wrapper:

gcc -shared -o libhot.so hot.o other.o

也可以使用編譯器直接生成動態庫:

gcc -fPIC -shared -o libhot.so hot.c other.c

這里選項 -shared 指示目標文件的類型是動態鏈接庫,動態庫的命名規范是”libyour_library_name.so”

linux操作系統中,

1.和靜態庫類似,動態庫文件也是一些目標文件(后綴名為.o)的集合體而已。

2.動態庫的后綴名是.so,對應于windows操作系統的后綴名為.dll的動態庫。

3.可以使用gcc命令來創建一個動態庫文件。

來看一個實例,和靜態庫的代碼實際是一樣的。先看看可以編譯成庫文件的源文件中的代碼:

/* test.c */ int f() { return 3; }

1

2

3

4

5

代碼非常簡單。我們敲入下列命令:

gcc -c -fPIC test.cgcc -shared -fPIC -o libtest.so test.o

1

2

會在當前目錄下生成一個libtest.so動態庫文件。再看如何使用這個庫。看如下代碼:

/* app.c */ #include extern int f(); int main() { printf(“return value is %d\n”,f()); return 0; }

1

2

3

4

5

6

7

8

敲入如下命令:

gcc –c app.cgcc -o app app.o -L. –ltest

1

2

敲命令的時候要記得將libtest.a文件和生成的app.o文件放在同一個目錄(即當前目錄)下。這樣,敲入命令后,會在當前目錄下生成一個名為app的可執行文件。但是當我們執行./app命令,來執行這個可執行文件時,卻提示如下錯誤:

這就奇怪了,libtest.so文件明明就在當前目錄下,為什么會提示找不到呢?? 原來linux和windows的機制是不同的,它不會在當前目錄下尋找動態連接庫文件,它只會在標準路徑下尋找。(The system searches only /lib and /usr/lib, by default.)。我們可以使用一個命令,使得操作系統去我們指定的路徑下面去尋找。假設libtest.so文件所在的目錄是/root/Desktop/aabb,那么執行命令

export LD_LIBRARY_PATH=/root/Desktop/aabb

1

后,再執行./app,我們發現,程序就正常運行了。

在加載動態鏈接庫的時候,有可能會遇到加載不到的錯誤,原因在于系統默認加載的動態鏈接庫路徑里沒有找到你的動態庫,有三種解決方法:

1.在執行gcc main.c -L. -ltest -o main 前,執行 export LD_LIBRARY_PATH=$(pwd)

2.將其添加到/etc/ld.so.cache文件中。將你so所在的目錄寫到/etc/ld.so.conf文件里,然后執行ldconfig該命令會重建/etc/ld.so.cache文件。

3.將你的so放在/etc/ld.so.conf里的路徑位置里。

Linux下的dlopen、dlsym、dlclose 相當于windows平臺的LoadLibrary、GetProcAddress 、FreeLibrary,可以在運行時動態加載動態庫,使用其中的導出函數。但是局限在于,這樣僅僅能夠導出全局函數,而不能導出類的方法。所以一般動態庫導出C++類實現的功能時都會設計一大堆的全局函數來包裝一下。? 包含頭文件:

#include dlfcn.h : Linux動態庫的顯式調用

1

函數

void * dlopen( const char * pathname, int mode );

1

函數描述:?   在dlopen的()函數以指定模式打開指定的動態連接庫文件,并返回一個句柄給調用進程。使用dlclose()來卸載打開的庫。?   mode:分為這兩種?   RTLD_LAZY 暫緩決定,等有需要時再解出符號?   RTLD_NOW 立即決定,返回前解除所有未決定的符號。

dlerror? 函數定義:

void*dlsym(void* handle,const char* symbol)

1

函數描述:? dlsym根據動態鏈接庫操作句柄(handle)與符號(symbol),返回符號對應的地址。使用這個函數不但可以獲取函數地址,也可以獲取變量地址。? dlclose

dlopen以指定模式打開指定的動態連接庫文件,并返回一個句柄給調用進程,dlerror返回出現的錯誤,dlsym通過句柄和連接符名稱獲取函數名或者變量名,dlclose來卸載打開的庫。 dlopen打開模式如下:

RTLD_LAZY 暫緩決定,等有需要時再解出符號?   RTLD_NOW 立即決定,返回前解除所有未決定的符號。? 生產動態鏈接庫

編譯參數 gcc -fPIC -shared

使用so文件的編譯參數? 編譯選項如下:

gcc -rdynamic -o main main.c -ldl

1

選項 -rdynamic 用來通知鏈接器將所有符號添加到動態符號表中? (目的是能夠通過使用 dlopen 來實現向后跟蹤)比如日志系統,主程序里使用一套日志系統,dlopen方式打開的libso里無法使用。編譯時加上這個參數,不需要增加任何代碼就可以使代碼通用。? 使用-ldl選項指明生成的對象模塊需要使用共享庫

總結

以上是生活随笔為你收集整理的linux系统中 库分为静态库和,你知道linux 静态库和共享库?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。