linux 下動態連接庫的製做與使用
動態連接庫*.so的編譯與使用- -
動態庫*.so在linux下用c和c++編程時常常會碰到,最近在網站找了幾篇文章介紹動態庫的編譯和連接,總算搞懂了這個以前一直不太瞭解得東東,這裏作個筆記,也爲其它正爲動態庫連接庫而苦惱的兄弟們提供一點幫助。
一、動態庫的編譯
下面經過一個例子來介紹如何生成一個動態庫。這裏有一個頭文件:so_test.h,三個.c文件:test_a.c、test_b.c、test_c.c,咱們將這幾個文件編譯成一個動態庫:libtest.so。
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_a.c:
#include "so_test.h"
void test_c()
{
printf("this is in test_c...\n");
}
將這幾個文件編譯成一個動態庫:libtest.so
$ gcc test_a.c test_b.c test_c.c -fPIC -shared -o libtest.so
二、動態庫的連接
在一、中,咱們已經成功生成了一個本身的動態連接庫libtest.so,下面咱們經過一個程序來調用這個庫裏的函數。程序的源文件爲:test.c。
test.c:
#include "so_test.h"
int main()
{
test_a();
test_b();
test_c();
return 0;
}
將test.c與動態庫libtest.so連接生成執行文件test:
$ gcc test.c -L. -ltest -o test
測試是否動態鏈接,若是列出libtest.so,那麼應該是鏈接正常了
$ ldd test
執行test,能夠看到它是如何調用動態庫中的函數的。
三、編譯參數解析
最主要的是GCC命令行的一個選項:
-shared 該選項指定生成動態鏈接庫(讓鏈接器生成T類型的導出符號表,有時候也生成弱鏈接W類型的導出符號),不用該標誌外部程序沒法鏈接。至關於一個可執行文件
-fPIC:表示編譯爲位置獨立的代碼,不用此選項的話編譯後的代碼是位置相關的因此動態載入時是經過代碼拷貝的方式來知足不一樣進程的須要,而不能達到真正代碼段共享的目的。
-L.:表示要鏈接的庫在當前目錄中
-ltest:編譯器查找動態鏈接庫時有隱含的命名規則,即在給出的名字前面加上lib,後面加上.so來肯定庫的名稱
LD_LIBRARY_PATH:這個環境變量指示動態鏈接器能夠裝載動態庫的路徑。
固然若是有root權限的話,能夠修改/etc/ld.so.conf文件,而後調用 /sbin/ldconfig來達到一樣的目的,不過若是沒有root權限,那麼只能採用輸出LD_LIBRARY_PATH的方法了。
四、注意
調用動態庫的時候有幾個問題會常常碰到,有時,明明已經將庫的頭文件所在目錄 經過 「-I」 include進來了,庫所在文件經過 「-L」參數引導,並指定了「-l」的庫名,但經過ldd命令察看時,就是死活找不到你指定連接的so文件,這時你要做的就是經過修改LD_LIBRARY_PATH或者/etc/ld.so.conf文件來指定動態庫的目錄。一般這樣作就能夠解決庫沒法連接的問題了linux