Linux下创建动态库与使用
參考文章:dll和so文件區別與構成:http://www.cnblogs.com/likwo/archive/2012/05/09/2492225.html
動態庫路徑配置- /etc/ld.so.conf文件:http://blog.csdn.net/blade2001/article/details/32839937
?
1.如何生成一個動態庫:
假設有4個文件(1個頭文件,3個.c源文件)so_test.h、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_c.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 2、動態庫的鏈接 在1、中,我們已經成功生成了一個自己的動態鏈接庫libtest.so,下面我們通過一個程序來調用這個庫里的函數。程序的源文件為:test.c。 test.c: #include "so_test.h" int main() { test_a(); test_b(); test_c(); return 0; } l ? ? ? ? 將test.c與動態庫libtest.so鏈接生成執行文件test: $ gcc test.c -L. -ltest -o test l ? ? ? ? 測試是否動態連接,如果列出libtest.so,那么應該是連接正常了 $ ldd test l ? ? ? ? 執行test,可以看到它是如何調用動態庫中的函數的。 但是此時出現以下問題:$>ldd test
linux-gate.so.1 => (0xb77c6000)
libtest.so => not found//動態庫未找到
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb75ea000)
/lib/ld-linux.so.2 (0xb77c7000)
但是查看當前目錄下明明有動態庫呀。
$>ls -l
總用量 36
-rwxrwxr-x 1 burgess burgess 6992 Dec 6 16:58 libtest.so
-rw-rw-r-- 1 burgess burgess 249 Dec 6 16:54 so_test.h
-rwxrwxr-x 1 burgess burgess 7372 Dec 6 17:00 test
-rw-rw-r-- 1 burgess burgess 189 Dec 6 16:55 test_a.c
-rw-rw-r-- 1 burgess burgess 189 Dec 6 16:56 test_b.c
-rw-rw-r-- 1 burgess burgess 209 Dec 6 17:00 test.c
-rw-rw-r-- 1 burgess burgess 189 Dec 6 16:57 test_c.c
執行./test卻出錯!
./test
./test: error while loading shared libraries: libtest.so: cannot open shared object file: No such file or directory
錯誤提示動態庫里沒有這個文件。
?
動態裝入器負責裝入動態鏈接的可執行程序運行所需的共享庫(shared library,即動態庫)。
ld.so.conf 文件包含一個所有目錄(/lib 和 /usr/lib 除外,它們會自動包含在其中)的清單,動態裝入器將在其中查找共享庫。
?
那么此時我們就需要把這個文件的路徑加入ld.so.conf 文件里了。
最省事的辦法就是通過/etc/ld.so.conf文件來指定動態庫的目錄(需要有root權限)。
#vi ?/etc/ld.so.conf?
里面顯示:
include /etc/ld.so.conf.d/*.conf
?/usr/local/lib
這里的“/usr/local”就是默認的動態庫路徑了。我們想要添加自己的路徑再起一行加入就OK。j假設“libtest.so”所在路徑是:“/home/burgess/gitlearn/test”
那么添加進去就變成了
include /etc/ld.so.conf.d/*.conf
?/usr/local/lib
/home/burgess/gitlearn/test
但是加進去了,退回到當前用戶再去$>ldd test還是顯示libtest.so => not found。
原來在動態裝入器能“看到”這一信息之前,必須將它轉換到 ld.so.cache 文件中。可以通過運行 ldconfig 命令做到這一點:
#ldconfig
另外,要查看 ldconfig 可以“看到”的所有共享庫,輸入: ?
# ldconfig -p | less
就可以查看libtest.so是否在顯示的庫列表里了。
?
?
最后,再執行:
$>ldd test
顯示動態庫就找到了:
linux-gate.so.1 => (0xb77dc000)
libtest.so => /home/burgess/gitlearn/test/libtest.so (0xb77b8000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb75fd000)
/lib/ld-linux.so.2 (0xb77dd000)
?
(下面這段話是照第二篇文章搬過來的,大家別拿板磚砸我。)
還有另一個方便的技巧可以用來配置共享庫路徑。有時候希望告訴動態裝入器在嘗試任何 /etc/ld.so.conf 路徑以前先嘗試使用特定目錄中的共享庫。在運行的較舊的應用程序不能與當前安裝的庫版本一起工作的情況下,這會比較方便。
LD_LIBRARY_PATH
要指示動態裝入器首先檢查某個目錄,請將 LD_LIBRARY_PATH 變量設置成您希望搜索的目錄。多個路徑之間用冒號分隔;例如:
# export LD_LIBRARY_PATH="/usr/lib/old:/home/burgess/gitlearn/test/lib"
導出 LD_LIBRARY_PATH 后,如有可能,所有從當前 shell 啟動的可執行程序都將使用 /usr/lib/old 或 /opt/lib 中的庫,如果仍不能滿足一些共享庫相關性要求,則轉回到 /etc/ld.so.conf 中指定的庫。
轉載于:https://www.cnblogs.com/Burgess-Fan/p/6138687.html
總結
以上是生活随笔為你收集整理的Linux下创建动态库与使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 梦到捞鱼是什么意思
- 下一篇: 梦到被丧尸追赶逃跑是什么预兆