linux下動態庫so檔案的一些認識

2021-06-29 14:18:31 字數 3173 閱讀 6200

from

對.so和.o檔案一直不太清楚,盜用別人的解釋的來了解一下。

個人創作,歡迎指錯。

牽扯到elf格式,gcc編譯選項待補,簡單實用的說明一下,對linux下的so檔案有個實際性的認識。

1. so檔案是什麼?

2. 怎麼生成以及使用乙個so動態庫檔案?

3. 位址空間,以及執行緒安全.

4. 庫的初始化,解析:

5. 使用我們自己庫里的函式替換系統函式:

也是elf格式檔案,共享庫(動態庫),類似於dll。節約資源,加快速度,**公升級簡化。

知道這麼多就夠了,實用主義。等有了印象再研究原理。

先寫乙個c檔案:s.c

#include 

int count;

void out_msg(const

char *m)

}

編譯:得到輸出檔案libs.o

gcc -fpic

-g-c s.c -o libs.o

乙個標頭檔案:s.h

#ifndef _my_so_header_  

#define _my_so_header_

void out_msg(const

char *m);

#endif

再來乙個c檔案來引用這個庫中的函式:ts.c

#include 

#include "s.h"

int main(int argc, char** argv)

gcc -g ts.c -o ts -l

.-ls

執行./ts,嗯:成功了。。。還差點

得到了ts:error while loading shared libraries: libs.so: cannot open shared object file: no such file or directory

系統不能找到我們自己定義的libs.so,那麼告訴他,修改變數ld_library_path,為了方便,寫個指令碼:e(檔名就叫e,懶得弄長了)

#!/bin/sh 

export ld_library_path=$:$

./ts

執行:./e &

螢幕上就開始不停有資訊輸出了,當然ts quit你是看不到的,前面是個死迴圈,後面會用到這句

如果這樣:./e &開始執行後,稍微等待一下然後再./e&

這個時候螢幕資訊會怎麼樣呢?全域性變數count會怎麼變化?

會是兩個程序交叉輸出資訊,並且各自的count互不干擾,雖然他們引用了同乙個so檔案。

也就是說只有**是否執行緒安全一說,沒有**是否是程序安全這一說法。

windows下的動態庫載入,解除安裝都會有初始化函式以及解除安裝函式來完成庫的初始化以及資源**,linux當然也可以實現。

elf檔案本身執行時就會執行乙個_init()函式以及_fini()函式來完成這個,我們只要把自己的函式能讓系統在這個時候執行

就可以了。

修改我們前面的s.c檔案:

#include 

void my_init(void) __attribute__((constructor)); //告訴gcc把這個函式扔到init section

void my_fini(void) __attribute__((destructor)); //告訴gcc把這個函式扔到fini section

void out_msg(const

char *m)

int i; //仍然是個計數器

void my_init(void)

void my_fini(void)

重新製作 libs.so,ts本是不用重新編譯了,**維護公升級方便很多。

然後執行:./e &

可以看到螢幕輸出:(不完整資訊,只是順序一樣)

init 

main

ok quit

fini

可以看到我們自己定義的初始化函式以及解析函式都被執行了,而且是在最前面以及最後面。

如果s.c中的sleep(5)沒有注釋掉,那麼有機會:

./e&

./e&連續執行兩次,那麼初始化函式和解析函式也會執行兩次,雖然系統只載入了一次libs.so。

如果sleep時候kill 掉後台程序,那麼解析函式不會被執行。

建立乙個新的檔案b.c:我們要替換系統函式malloc以及free(可以自己寫個記憶體洩露檢測工具了)

#include 

void* malloc(int size)

void

free(void* ad)

gcc -fpic

-g-c b.c -o libb.o

gcc -g

-shared

-wl,-soname,libb.so -o libb.so -lc

修改s.c:重新生成libs.so

void out_msg()  

修改指令碼檔案e:

#!/bin/sh 

export ld_preload=$libb.so:$

export ld_library_path=$:$

./ts

關鍵就在ld_preload上了,這個路徑指定的so將在所有的so之前載入,並且符號會覆蓋後面載入的so檔案中的符號。如果可執行檔案的許可權不合適(sid),這個變數會被忽略。

執行:./e &

嗯,可以看到我們的malloc,free工作了。

暫時就想到這麼多了。

linux下動態庫 so檔案用法總結

linux下庫檔案有兩種 一是靜態庫檔案,以.a為字尾的檔案。二是動態庫檔案,以.so為字尾的檔案。其二者主要區別在於靜態庫是在編譯時載入,而動態庫是在執行時載入。關於靜態庫檔案使用比較繁多,在makefile中的使用如下例 libs l.l rootpath lib ltest 這裡載入的靜態庫檔...

Linux下動態庫 so 和靜態庫 a

一般情況下,在專案裡會把功能相似的 封裝成庫,方便使用和管理,同時增加了 的內聚性。庫分為兩種,一種為靜態庫,檔名以.a結尾,另一種是動態庫,檔名以.so結尾。靜態庫和動態庫的使用各有利弊。靜態庫的特點 動態庫的特點 現在用乙個微型的工程,來講述靜態庫 動態庫的生成和使用。假設有3個.c檔案,分別為...

linux下動態庫( so 的路徑問題

最近在使用wxwidgets,這是乙個跨平台的c 庫,在linux下編譯成動態庫 so 如果將編譯後的可執行檔案發布到其他機器的linux系統中,需要帶上.so檔案,這就需要設定一下這些動態庫的路徑,一般可以使用環境變數ld library path來設定,可以在終端中直接輸出如下的命令 expor...