經過一個例子來介紹如何生成一個動態庫。假設有一個頭文件so_test.h和三個C文件:test_a.c、test_b.c、test_c.c linux
/* so_test.h */ #include <stdio.h> #include <stdlib.h> void test_a(); void test_b(); void test_c();
/* test_a.c */ #include "so_test.h" void test_a(){ printf("this is in test_a...\n"); }
/* test_b.c */ #include "so_test.h" void test_b(){ printf("this is in test_b...\n"); }
/* test_c.c */ #include "so_test.h" void test_c(){ printf("this is in test_c...\n"); }
將這幾個文件編譯成一個動態庫:libtest.so
shell
gcc test_a.c test_b.c test_c.c -fPIC -shared -o libtest.so參數說明:
-shared 該選項指定生成動態鏈接庫(讓鏈接器生成T類型的導出符號表,有時候也生成弱鏈接W類型的導出符號),不用該標誌外部程序沒法鏈接。至關於一個可執行文件
-fPIC 表示編譯爲位置獨立的代碼,不用此選項的話編譯後的代碼是位置相關的因此動態載入時是經過代碼拷貝的方式來知足不一樣進程的須要,而不能達到真正代碼段共享的目的。
若是在windows下使用MinGW進行編譯,則要將上述命令中的libtest.so改爲libtest.dll windows
下面編寫一個test.c調用剛生成的動態連接庫libtest.so: this
/* test.c */ #include "so_test.h" int main(){ test_a(); test_b(); test_c(); return 0; }使用以下的命令將test.c編譯成test.o,並和libtest.so連接到一塊兒造成 可執行文件test
gcc test.c -L. -ltest -o test參數說明:
-L.:表示要鏈接的庫在當前目錄中(也能夠設置環境變量LD_LIBRARY_PATH進行指定)
-ltest:編譯器查找動態鏈接庫時有隱含的命名規則,即在給出的名字前面加上lib,後面加上.so來肯定庫的名稱 spa
執行./test看可否輸出指望的結果: code
this is in test_a... this is in test_b... this is in test_c...
[test@192.168.1.102 ~/workspace/so$]ldd test linux-gate.so.1 => (0x00c5f000) libtest.so (0x00c20000) libc.so.6 => /lib/libc.so.6 (0x00157000) /lib/ld-linux.so.2 (0x00131000)
調用動態庫的時候有幾個問題會常常碰到,有時,明明已經將庫的頭文件所在目錄 經過 「-I」 include進來了,庫所在文件經過 「-L」參數引導,並指定了「-l」的庫名,但經過ldd命令察看時,就是死活找不到你指定連接的so文件,這時你要做的就是經過修改 LD_LIBRARY_PATH或者/etc/ld.so.conf文件來指定動態庫的目錄。一般這樣作就能夠解決庫沒法連接的問題了。
進程