文章詳情頁(yè)
solaris中有類似windows的DLL有關(guān)的函數(shù)嗎?
瀏覽:6日期:2024-02-05 08:22:37
【 在 irene (yoyo) 的大作中提到: 】 : 如題 呵呵當(dāng)然有,window那套動(dòng)?xùn)|東很多機(jī)制都是抄Unix的 比如system(32)*.dll是就是仿照unix的/usr/lib/*.so unix的/usr/lib/*.so就是unix的動(dòng)態(tài)庫(kù)(dynamic library) 給程序動(dòng)態(tài)鏈接用的,反之/usr/lib/*.a是靜態(tài)庫(kù),程序編譯 鏈接時(shí)就將相關(guān)函數(shù)鏈入目標(biāo)文件。 實(shí)際上泥cc -o yyy yyy.o -lXXX那個(gè)XXX就是告訴cc找/usr/lib/libXXX.so.. yyy.o聲明調(diào)用了libXXX.so中的函數(shù),鏈接成功的目標(biāo)文件yyy在運(yùn)行時(shí)將動(dòng)態(tài) 調(diào)用libXXX.so的函數(shù),至于cc -o yyy yyy.o libxxx.a那就不同了呵呵 cc對(duì)-l參數(shù)的缺省鏈接方式是動(dòng)態(tài)鏈接,即只鏈接符號(hào),不鏈入函數(shù)實(shí)體。 對(duì)鏈接方式可man ld。 言歸正傳,既然有動(dòng)態(tài)庫(kù),就肯定有與之相關(guān)的函數(shù),window有LoadLibrary, 偶Solaris有dlopen,就是dynamic library open,window能讓泥做 土版DLL,偶solaris早就能讓泥自己生產(chǎn).so了呵呵,下面具體說(shuō)明怎樣調(diào)用 動(dòng)態(tài)庫(kù)libXXX里的函數(shù)而又不需要在cc中指定-lXXX。 首先是dlopen,格式: #include void * dlopen(const char *pathname, int mode); 返回一個(gè)void *類型的handle,否則返回NULL。 pathname就是泥所要打開(kāi)的動(dòng)態(tài)庫(kù),如果這個(gè)庫(kù)聲明鏈接了其它庫(kù),即對(duì)其它 庫(kù)有依賴關(guān)系,那么所有相關(guān)有依賴關(guān)系的庫(kù)都會(huì)被打開(kāi),這些打開(kāi)的庫(kù)稱之 為組(group)。 mode是打開(kāi)方式: RTLD_LAZY:打開(kāi)動(dòng)態(tài)庫(kù)后只重定位庫(kù)中數(shù)據(jù)地址引用而不重定位而函數(shù)引用, 函數(shù)引用在該函數(shù)要被激活時(shí)才定位,的確LAZY呵呵,但省開(kāi)銷;) RTLD_NOW: 與上者相比,動(dòng)態(tài)庫(kù)一被打開(kāi)就重定位所有函數(shù)的引用。 RTLD_GLOBAL:打開(kāi)動(dòng)態(tài)庫(kù)里的全局符號(hào)可以被其它所有庫(kù)重定位。 RTLD_LOCAL: 打開(kāi)動(dòng)態(tài)庫(kù)里的全局符號(hào)只能被同組庫(kù)重引用。 RTLD_GROUP: 只有相關(guān)組的符號(hào)才允許重定位?? RTLD_PARENT:發(fā)dlopen調(diào)用的對(duì)象中的符號(hào)對(duì)被dlopen對(duì)象可見(jiàn)。 RTLD_WORLD: 。。。呵呵太晦澀了我翻譯的我都看不明白;( 總之,一個(gè)RTLD_LAZY已經(jīng)夠用了呵呵;) 然后是得到重定位的數(shù)據(jù)或函數(shù)引用: #include void *dlsym(void *handle, const char *name) 意義明顯,handle即dlopen的返回值,name即泥要引用的在動(dòng)態(tài)庫(kù)變量或函 數(shù)名稱。成功返回重定位后的符號(hào)地址,失敗返回NULL。 最后是關(guān)閉動(dòng)態(tài)庫(kù):int dlclose(void *handle), 一看就明白,懶得解釋了;) 下面給一個(gè)例子增加感性認(rèn)識(shí),該例子調(diào)用動(dòng)態(tài)庫(kù)clIEnt.so中的函數(shù) int client_request(char *),該函數(shù)返回0或-1并根據(jù)不同錯(cuò)誤設(shè)置 字符串err_info(也定義在client.so中): # include # include # include # define TRUE 0 # define FALSE -1 main( ) { char buf[64]; void *handle; /* 動(dòng)態(tài)庫(kù)句柄 */ char *err_info; /* 要引用的動(dòng)態(tài)庫(kù)中的一個(gè)變量 */ int (*client_request)(char *); /* 要引用的一個(gè)函數(shù) */ /* 打開(kāi)動(dòng)態(tài)庫(kù)client.so */ if ((handle = dlopen('client.so', RTLD_LAZY)) == NULL) { perror('dlopen'); exit(-1); } /* 得到函數(shù)名client_request的引用 */ if ((client_request = (int (*)(char *))dlsym(handle, 'client_request')) == NULL) { perror('dlsym client_request'); exit(-1); } /* 得到變量名err_info的引用 */ if ((err_info = (char *)dlsym(handle, 'err_info')) == NULL) { perror('dlsym err_info'); exit(-1); } for(;;) { gets(buf); /* 從標(biāo)準(zhǔn)輸入讀入命令串 */ if (strcmp(buf, 'exit') == TRUE) { dlclose(handle); /* 關(guān)閉動(dòng)態(tài)庫(kù) */ return 0; } printf('request:%sn', buf); client_request(buf); /* 調(diào)用動(dòng)態(tài)庫(kù)中的函數(shù) */ printf('ask: %sn', err_info); /* 引用動(dòng)態(tài)庫(kù)中的變量 */ } } 最后是編譯問(wèn)題,怎樣編譯成.so文件呢?很簡(jiǎn)單用ld或者cc -G就可以了,比如: cc -G yyy.so yyy.o others.o -ldl 如果這個(gè)yyy.o有引用了其它動(dòng)態(tài)庫(kù)的函數(shù)呢?那么用cc -G ... -l了 比如yyy.o引用了socket函數(shù),那么 cc -G yyy.so yyy.o others.o -ldl -lsocket即可。
標(biāo)簽:
Windows系統(tǒng)
排行榜
