LINUX下動態鏈接庫的創建 |
在LINUX系統下,創建動態鏈接庫是件很簡單的事情。只要在編譯函數庫源程序時加上-shared選項即可,這樣所生成的執行程序即爲動態鏈接庫。從某種意義上來說,動態鏈接庫也是一種執行程序。按一般規則,程序名應帶.so後綴。下面舉個例子。 |
編寫兩個函數,一個用於查詢當前日期getdate,一個用於查詢當前時間gettime,並將這兩個函數存於動態鏈接庫my.so中。爲此,需要做以下幾項工作。 |
1.1 編寫用戶接口文件datetime.h,內容如下(每行前面的數字爲行號) |
---------------------------------------------------------------------- |
1 /* datetime.h |
2 |
3 #ifndef __DATETIME_H |
4 |
5 #define __DATETIME_H |
6 |
7 /* 日期結構 */ |
8 typedef struct |
9 { |
10 int year; |
11 int mon; |
12 int day; |
13 }DATETYPE; |
14 |
15 /* 時間結構 */ |
16 typedef struct |
17 { |
18 char hour; |
19 char min; |
20 char sec; |
21 }TIMETYPE; |
22 |
23 /* 函數原型說明 */ |
24 |
25 #ifdef SHARED |
26 int (*getdate)(DATETYPE *d); |
27 #else |
28 int getdate(DATETYPE *d); |
29 #endif |
30 |
31 #ifdef SHARED |
32 int (*gettime)(TIMETYPE *t); |
33 #else |
34 int gettime(TIMETYPE *t); |
35 #endif |
36 |
37 #endif |
38 |
---------------------------------------------------------------------- |
這個用戶接口文件中,先定義了日期與時間結構,接着定義一下函數的原 型。動態函數與靜態函數的原型說明不同的是,動態函數應使用(*函數名)的 形式,以便引用其指針。若要引用文件中的動態函數說明,用戶應該定義一 下SHARED宏,這樣才能使用。 |
1.2 編寫getdate.c,源程序如下: |
---------------------------------------------------------------------- |
1 /* getdate.c |
2 |
3 #i nclude "time.h" |
4 #i nclude "datetime.h" |
5 |
6 int getdate(DATETYPE *d) |
7 { |
8 long ti; |
9 struct tm *tm; |
10 |
11 time(&ti); |
12 tm=localtime(&ti); |
13 d->year=tm->tm_year+1900; |
14 d->mon=tm->tm_mon+1; |
15 d->day=tm->tm_mday; |
16 } |
17 |
---------------------------------------------------------------------- |
在getdate函數中,先調用time取得以秒計的系統時間,再用localtime函數 轉換一下時間結構,最後調整得到正確的日期。 |
1.3 編寫gettime.c,源程序如下: |
---------------------------------------------------------------------- |
1 /* gettime.c |
2 |
3 #i nclude "time.h" |
4 #i nclude "datetime.h" |
5 |
6 int gettime(TIMETYPE *t) |
7 { |
8 long ti; |
9 struct tm *tm; |
10 |
11 time(&ti); |
12 tm=localtime(&ti); |
13 t->hour=tm->tm_hour; |
14 t->min=tm->tm_min; |
15 t->sec=tm->tm_sec; |
16 } |
17 |
---------------------------------------------------------------------- |
gettime函數與getdate函數相仿,先用time函數取得以秒計的系統時間,再 用localtime函數轉換一下時間結構,最後返回當前的時間(不需調整)。 |
1.4 編寫維護文件makefile-lib,內容如下: |
---------------------------------------------------------------------- |
1 # makefile-lib |
2 |
3 all : my.so |
4 |
5 SRC = getdate.c gettime.c |
6 |
7 TGT = $(SRC:.c=.o) |
8 |
9 $(SRC) : datetime.h |
10 @touch $@ |
11 |
12 %.o : %.c |
13 cc -c $? |
14 |
15 # 動態函數庫(my.so)生成 |
16 my.so : $(TGT) |
17 cc -shared -o $@ $(TGT) |
18 |
---------------------------------------------------------------------- |
編寫維護文件的目的,在於方便程序員維護程序,尤其是維護比較大的工程項目。一個素質良好的程序員應該學會熟練地編寫維護文件makefile。定義了文件間的依賴關係後,一旦源文件發生變化,僅需make一下,其目標文件維護代碼會自動執行,從而自動更新目標文件,減少了許多工作量。注意: 每行維護代碼必須以TAB(跳格鍵)開始,不是的話make時將出錯。 |
本維護文件第1行是註釋行,以#號開頭;文件第3行定義所有需要維護的函數庫;第5行定義相關源程序文件;第7行定義目標文件;第9-10行說明所有源程序依賴於datetime.h頭文件,並有相應維護代碼,即touch一下,更新一下源文件的時間;第12-13行定義.o文件依賴於相應的.c文件,並指定了維護代碼,即用cc編譯一下;第16-17行定義共享庫my.so依賴的目標文件,維護代碼中用-shared編譯選項,以生成動態鏈接庫my.so。 |
1.5 運行make -f makefile-lib 命令 |
make運行後,動態鏈接庫my.so就產生了,我們就可以在程序中調用了。如果想讓系統所有用戶都可以使用,則應以root用戶登錄系統,將這個庫拷貝到/lib目錄下(命令:cp my.so /lib),或者在/lib目錄下建個符號連接即可(命令:ln -s `pwd`/my.so /lib)。 |