大家對windows作業系統中的dll檔案一定十分熟悉,其實這種軟體元件化的方法在linux中也可以實現。其實外掛程式和 dll 通常是用來無須編寫整個新應用程式而新增功能的極好方法,一般來講,在不更改原有應用程式的情況下,外掛程式為現有應用程式提供新功能。linux環境下甚至做的更好。
linux提供4個庫函式、乙個標頭檔案dlfcn.h以及兩個共享庫(靜態庫libdl.a和動態庫libdl.so)支援動態鏈結。
? dlsym:返回鎖請求的入口點的指標
? dlerror:返回null或者指向描述最近錯誤的字串
? dlclose:關閉動態共享檔案
函式dlopen需要在檔案系統中查詢目標檔案並為之建立控制代碼。有四種方法指定目標檔案的位置:
? 絕對路徑
? 在環境變數ld_library_path指定的目錄中
? 在/etc/ld.so.cache中指定的庫列表中
? 在/usr/lib或者/lib中
下面舉乙個例子。
主程式檔案hello.c:
#include
#include
void* slib=0;
void (*func)(char*);
const char* herror;
int main(int argc,char* ar**)
func=dlsym(slib,"func");
herror=dlerror();
if (herror)
func("how do you do?/n");
dlclose(slib);
herror=dlerror();
if (herror)
return 0;
}函式dlopen的第二個引數有兩種選擇:
? rtld_lazy:推遲解析dll中的外部引用,直到dll被執行
? rtld_now:在返回之前解析所有的外部引用
以下是dll檔案原始碼slib.c:
int func(char* msg)
是不是很簡單?
all:hello slib.so
hello:
gcc -o hello hello.c -ldl
slib.so:slib.o
gcc -shared -lc -o slib.so slib.o
slib.o:
gcc -c -fpic slib.c
生成這個程式需要三步:
? 將dll編譯為位置無**
? 建立dll共享目標檔案
? 編譯主程式並與dll相鏈結
編譯slib.c時,使用了-fpic或者-fpic選項,使生成的**是位置無關的,因為重建共享目標庫需要位置無關,並且這類**支援大的偏移。
建立dll共享目標檔案時使用了-shared選項,該選項產生適合動態鏈結的共享目標檔案slib.so。
生成主程式時,使用-ldl選項,這是鏈結選項,即主程式中的部分符號為動態鏈結庫中的符號,也就是說,在執行時需要到dll檔案中才能夠解決引用。
二.通用型別的動態函式庫的建立
linux作業系統和各種軟體包為軟體開發人員提供了很多的動態函式庫檔案。但是一般情況下這些庫還不能滿足使用者的所有需求。開發人員會根據自己的需要編寫很多的函式。對於這些函式,如果總是將原始檔與呼叫它們的程式鏈結起來,雖然也可以,但是,缺點是顯然的。下面就將它們加入動態函式庫中。
在linux中,建立動態函式庫不需要額外的工具,只需要gcc就可以了。
通過ldd命令可以很方便的察看程式用到了哪些庫。
下面通過乙個簡單的例子說明動態函式庫的建立過程。
檔案mylib.c是函式庫的源程式檔案,內容如下:
int myadd(int a1, int a2)
檔案testlib.c是測試程式的源程式檔案:
#incoude
extern int myadd(int, int);
int main()
下面給出makefile的內容:
all:libmylib.so.1.0 testlib
libmylib.so.1.0 : mylib.o
ld –m elf_i386 –shared –soname libmylib.so.1 –o libmylib.so.1.0 mylib.o
ln –sf libmylib.so.1.0 libmylib.so.1
ln –sf libmylib.so.1 libmylib.so
testlib : testlib.c
gcc –wall –o2 –l. –lmylib –o testlib testlib.c
mylib.o : mylib.c
gcc –c –wall –o2 –fpic –o mylib.o mylib.c
clean :
-rm –f libmylib.so* testlib *.o
在linux的shell中輸入make命令,動態函式庫libmylib.so.1.0和它的測試程式就生成了。執行./testlib試試看。
如果你不走運的話,系統會提示找不到libmylib.so.1動態函式庫,因為系統認為沒有這樣的檔案或目錄。不要慌。你可能需要使用ld_library_path環境變數。
[root@localhost home]export ld_library_path=.:$ld_library_path
再執行一次測試程式吧。
動態連線庫
windows下動態鏈結庫的編寫 在vc中新建乙個空的win32動態鏈結庫工程 win32 domanic library 然後新增乙個c sourse file到工程,我這裡的檔名取dlltest.cpp。然後在檔案中新增如下內容 declspec dllexport int add int a,...
linux動態庫與靜態庫混合連線
1,在應用程式需要連線外部庫的情況下,linux預設對庫的連線是使用動態庫,在找不到動態庫的情況下再選擇靜態庫。使用方式為 gcc test.cpp l.ltestlib 如果當前目錄有兩個庫libtestlib.so libtestlib.a 則肯定是連線libtestlib.so。如果要指定為連...
生成動態連線庫 靜態連線庫的 makefile
靜態連線庫 擴充套件名為 a 是.o檔案的簡單集合。在 linux unix下,使用 ar 命令生成靜態連線庫。動態連線庫 擴充套件名為.so 是將.o檔案集合,並增加了匯出表。匯出表是乙個函式名 函式索引 函式位址的陣列。因此,應用程式可以裝載 使用 ldopen函式 後,根據函式名,匯出函式的索...