歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Linux編程練習(二)—— Linux下.so動態庫的建立和調用

Linux編程練習(二)—— Linux下.so動態庫的建立和調用

日期:2017/3/1 9:51:19   编辑:Linux編程

(在Ubuntu 12.04系統下進行測試)

實現將一個自己編寫的Hello.c文件打包成libHello.so動態庫,並通過gcc編譯工具實現用一個test.c程序調用libHello.so和自定義頭文件Hello.h的過程。

具體程序代碼如下:

//Hello.h文件

include <stdio.h>
void printhello();

//Hello.c文件

#include <stdio.h>
void printhello()
{
puts("Hello World!");
}

//test.c文件

#include <Hello.h>
int main()
{
printhello();
return 0;
}

具體操作過程:
第一步:
將文件Hello.c編譯成一個動態庫:libHello.so,執行命令如下:

$ gcc Hello.c -fPIC -shared -o libHello.so

-shared: 該選項指定生成動態連接庫(讓連接器生成T類型的導出符號表,有時候也生成弱連接W類型的導出符號),不用該標志外部程序無法連接,相當於一個可執行文件;

-fPIC:表示編譯為位置獨立的代碼,不用此選項的話編譯後的代碼是位置相關的,所以動態載入時是通過代碼拷貝的方式來滿足不同進程的需要,而不能達到真正代碼段共享的目的。


第二步:
生成Hello.c文件的動態鏈接庫libHello.so以後,直接在包含Hello.h和libHello.so文件夾底下運行如下gcc命令:

$ gcc test.c -lHello -L. -I. -o test

-L.:-L後跟連接庫的路徑,‘.’表示要連接的庫在當前目錄中;

-I.:表示要連接的頭文件在當前目錄;

-lHello:編譯器查找動態連接庫時有隱含的命名規則,即在給出的名字前面加上lib,後面加上.so來確定庫的名稱(即:libHello.so)。


第三步:
執行命令“$ ldd test” 打印test可執行文件的動態庫依賴關系,結果輸出:

linux-vdso.so.1 => (0x00007fff16b8a000)
libHello.so => not found
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa55700c000)
/lib64/ld-linux-x86-64.so.2 (0x00007fa5573e4000)

其中,“libHello.so => not found”表明鏈接程序找不到libHello.so文件,這是因為鏈接程序只尋找固定目錄(一般為/lib和/usr/lib),解決方法有兩種:
方法一:把libHello.so拷貝到鏈接程序的搜索路徑目錄下(/lib或/usr/lib)。
方法二:設置環境變量LD_LIBRARY_PATH,增加當前路徑到該變量中。
配置環境變量的方法為:


LD_LIBRARY_PATH = LD_LIBRARY_PATH:"當前路徑名";
export LD_LIBRARY_PATH

這裡采用第一種解決方法,再次執行“$ ldd test”,此時顯示:


linux-vdso.so.1 => (0x00007fff6c7d7000)
libHello.so => /lib/libHello.so (0x00007f818dce3000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f818d923000)
/lib64/ld-linux-x86-64.so.2 (0x00007f818defd000)


libHello.so=>後有值,說明查找動態庫成功。
執行“./test”命令,正確輸出相應結果。

Copyright © Linux教程網 All Rights Reserved