一、靜態庫的建立和使用:
1、產生靜態庫 :庫名 libmylib.a
ar rcs libmylib.a mylib.o
2、將靜態庫copy到 /usr/lib/ 或/lib/ 目錄下
cp libmylib.a /usr/lib/
3、靜態庫的使用
比如測試檔案為test.c
gcc -0 test test.c -lmylib
-l為選項, mylib為庫名。mylib為libmylib的中間部分,Linux下約定所有庫都以首碼lib開始
靜態庫以.a結尾,動態庫以.so結尾。再編譯程式時,無需帶上首碼和尾碼。
注意:靜態庫的命名需要以"lib"開頭,否者串連是編譯器無法找到庫
二、動態庫的建立和使用:
1、下面命令把mylib.c程式建立成了一個動態庫
(1)、gcc -fPIC -o mylib.o -c mylib.c
(2)、gcc -shared -o libttt.so mylib.o
也可以直接使用一條命令
gcc -fPIC -shared -o libttt.so mylib.c
2、Linux有兩種方式調用動態庫串連中的函數
(1)、gcc -o test test.c ./libttt.so
(2)、cp libttt.so /usr/lib/libttt.so
gcc -o test test.c /usr/lib/libttt.so
注意:引用動態庫時,必須含有路徑,如果只是使用libttt.so,則必須確保這個庫所在目錄包括再PATH 環境變數中
三、系統函數使用動態庫:
1、void *dlopen(const char *filename, int flag)
用於開啟指定名字的動態連結程式庫,並返回一個控制代碼
flag:RTLD_LAZY, RTLD_NEW, RTLD_GLOBAL
RTLD_LAZY:在dlopen()返回前,對於動態庫中存在的未定義的變數(如外部變extern,也可以是函數)
不執行解析,也就是不解析這個變數的地址
RTLD_NEW:與RTLD_LAZY 不同,在dlopen()返回前,解析處每個未定義的變數的地址,如果解析不出來,dlopen會返回NULL,錯位為"undefined symbol:xxx..."
RTLD_GLOBAL:是庫中被解析出來的變數在隨後的其它連結庫中也可以使用,即全域有效。
2、void *dlsym(void *handle, char *symbol)
根據動態連結程式庫的控制代碼與函數名,返回函數名對應的函數的地址。
3、int dlclose(void *handle)
關閉動態連結程式庫,handle是調用dlopen函數庫的控制代碼
4、const char *dlerror(void)
動態庫連結庫執行失敗時,dlerror返回錯誤資訊,若執行成功,則返回NULL
例子:
main.cint main(void){void *handle;char *error;void (*welcome)();if ((handle = dlopen("./libttt.so", RTLD_LAZY)) == NULL){printf("dlopen error");return -1;}welcome = dlsym(handle, "welcome");if ((error = dlerror()) != NULL){printf("dlsym error");return -1;}welcome();dlclose(handle);return 0;}gcc -ldl -o main main.c |
-ldl 指明dlopen函數所在的庫。
注意:dlopen("./libttt.so", RTLD_LAZY),的目錄是在目前的目錄下,如果不在目前的目錄下,程式運行錯誤
共用庫進行更新或安裝新庫後,必須運行ldconfig命令更新/etc/ld.conf檔案中相應的項
如果使用RPM進行安裝,一般會自動進行更新,不過也不能保證這一點。
使用數學庫時加上 -lm
gcc -lm
庫工具使用:
ldd 工具
ldd 用來顯示執行檔案需要哪些共用庫, 共用庫裝載管理器在哪裡找到了需要的共用庫。