Linux動態庫生成與使用指南
相關閱讀: Linux靜態庫生成指南
Linux下動態庫檔案的檔名形如 libxxx.so
,其中so是 Shared Object 的縮寫,即可以共享的目標檔案。
在連結動態庫生成可執行檔案時,並不會把動態庫的程式碼複製到執行檔案中,而是在執行檔案中記錄對動態庫的引用。
程式執行時,再去載入動態庫檔案。如果動態庫已經載入,則不必重複載入,從而能節省記憶體空間。
Linux下生成和使用動態庫的步驟如下:
- 編寫原始檔。
- 將一個或幾個原始檔編譯連結,生成共享庫。
- 通過
-L<path> -lxxx
的gcc選項鍊接生成的libxxx.so。 - 把libxxx.so放入連結庫的標準路徑,或指定
LD_LIBRARY_PATH
,才能執行連結了libxxx.so的程式。
下面通過例項詳細講解。
編寫原始檔
建立一個原始檔: max.c,程式碼如下:
int max(int n1, int n2, int n3)
{
int max_num = n1;
max_num = max_num < n2? n2: max_num;
max_num = max_num < n3? n3: max_num;
return max_num;
}
編譯生成共享庫:
gcc -fPIC -shared -o libmax.so max.c
我們會得到libmax.so。
實際上上述過程分為編譯和連結兩步, -fPIC是編譯選項,PIC是 Position Independent Code 的縮寫,表示要生成位置無關的程式碼,這是動態庫需要的特性; -shared是連結選項,告訴gcc生成動態庫而不是可執行檔案。
上述的一行命令等同於:
gcc -c -fPIC max.c
gcc -shared -o libmax.so max.o
為動態庫編寫介面檔案
為了讓使用者知道我們的動態庫中有哪些介面可用,我們需要編寫對應的標頭檔案。
建立 max.h ,輸入以下程式碼:
#ifndef __MAX_H__
#define __MAX_H__
int max(int n1, int n2, int n3);
#endif
測試,連結動態庫生成可執行檔案
建立一個使用max
函式的test.c,程式碼如下:
#include <stdio.h>
#include "max.h"
int main(int argc, char *argv[])
{
int a = 10, b = -2, c = 100;
printf("max among 10, -2 and 100 is %d.\n", max(a, b, c));
return 0;
}
gcc test.c -L. -lmax
生成a.out,其中-lmax
表示要連結libmax.so
。
-L.
表示搜尋要連結的庫檔案時包含當前路徑。
注意,如果同一目錄下同時存在同名的動態庫和靜態庫,比如 libmax.so
和 libmax.a
都在當前路徑下,
則gcc會優先連結動態庫。
執行
執行 ./a.out
會得到以下的錯誤提示。
./a.out: error while loading shared libraries: libmax.so: cannot open shared object file: No such file or directory
找不到libmax.so,原來Linux是通過 /etc/ld.so.cache
檔案搜尋要連結的動態庫的。
而 /etc/ld.so.cache
是 ldconfig 程式讀取 /etc/ld.so.conf
檔案生成的。
(注意, /etc/ld.so.conf
中並不必包含 /lib
和 /usr/lib
,ldconfig
程式會自動搜尋這兩個目錄)
如果我們把 libmax.so
所在的路徑新增到 /etc/ld.so.conf
中,再以root許可權執行 ldconfig
程式,更新 /etc/ld.so.cache
,a.out
執行時,就可以找到 libmax.so
。
但作為一個簡單的測試例子,讓我們改動系統的東西,似乎不太合適。
還有另一種簡單的方法,就是為a.out
指定 LD_LIBRARY_PATH
。
LD_LIBRARY_PATH=. ./a.out
程式就能正常執行了。LD_LIBRARY_PATH=.
是告訴 a.out
,先在當前路徑尋找連結的動態庫。
對於elf格式的可執行程式,是由ld-linux.so*來完成的,它先後搜尋elf檔案的
DT_RPATH
段, 環境變數LD_LIBRARY_PATH
, /etc/ld.so.cache檔案列表, /lib/,/usr/lib目錄, 找到庫檔案後將其載入記憶體. (http://blog.chinaunix.net/uid-23592843-id-223539.html)
makefile讓工作自動化
編寫makefile,內容如下:
.PHONY: build test clean
build: libmax.so
libmax.so: max.o
gcc -o $@ -shared $<
max.o: max.c
gcc -c -fPIC $<
test: a.out
a.out: test.c libmax.so
gcc test.c -L. -lmax
LD_LIBRARY_PATH=. ./a.out
clean:
rm -f *.o *.so a.out
make build
就會生成libmax.so
, make test
就會生成a.out
並執行,make clean
會清理編譯和測試結果。
2015-03-11 Wed
相關文章
- Linux 動態庫生成與使用指南Linux
- VS下生成與配置靜態庫與動態庫(一)
- linux下生成動態連結庫Linux
- linux靜態庫的生成與使用(轉)Linux
- linux下的靜態庫與動態庫Linux
- cmake:生成靜態庫和動態庫
- Linux 靜態庫生成指南Linux
- Linux 中的靜態庫和動態庫簡介及生成過程示例Linux
- Linux 依賴動態庫 / 靜態庫的動態態庫 / 靜態庫Linux
- Linux 靜態庫生成及呼叫Linux
- Linux下靜態庫生成指南Linux
- Linux 動態庫與靜態庫製作及使用詳解Linux
- Linux系統下Qt動態庫的生成已經動態庫的使用例項圖解LinuxQT圖解
- Linux動態庫Linux
- Linux下的靜態庫、動態庫和動態載入庫Linux
- Linux共享庫、靜態庫、動態庫詳解Linux
- LINUX庫的使用與生成(轉)Linux
- Linux下的共享庫(動態庫)和靜態庫Linux
- 靜態庫生成
- 動態連結庫與靜態連結庫
- 菜鳥教程——iOS動態庫與靜態庫iOS
- ios靜態庫與動態庫的區別iOS
- linux 動態庫 靜態庫 函式覆蓋Linux函式
- 在Linux中建立靜態庫和動態庫Linux
- 使用.Net Core RT 生成標準動態庫
- Linux 動態庫 undefined symbol 原因定位與解決方法LinuxUndefinedSymbol
- 簡述Linux下的靜態庫和動態庫Linux
- Linux靜態庫和動態庫學習總結Linux
- Linux環境下建立靜態庫和動態庫Linux
- C++靜態庫與動態庫深入研究C++
- 跨模組介面與動態庫
- Android:JNI與NDK(二)交叉編譯與動態庫,靜態庫Android編譯
- ajax動態生成table
- linux shell 動態生成 陣列系列 seq使用技巧Linux陣列
- Linux Shell 動態生成 陣列系列 Seq 使用技巧Linux陣列
- 資料庫與動態規劃資料庫動態規劃
- LINUX系統中動態連結庫的建立與使用(轉)Linux
- linux下靜態庫、動態庫編譯及makefile書寫Linux編譯