日本免费全黄少妇一区二区三区-高清无码一区二区三区四区-欧美中文字幕日韩在线观看-国产福利诱惑在线网站-国产中文字幕一区在线-亚洲欧美精品日韩一区-久久国产精品国产精品国产-国产精久久久久久一区二区三区-欧美亚洲国产精品久久久久

Solaris 中類(lèi)似 Windows 的DLL有關(guān)的函數(shù)

【Solaris 中類(lèi)似 Windows 的DLL有關(guān)的函數(shù)】
如題
呵呵當(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 *類(lèi)型的handle,否則返回NULL 。

pathname就是泥所要打開(kāi)的動(dòng)態(tài)庫(kù),如果這個(gè)庫(kù)聲明鏈接了其它庫(kù),即對(duì)其它
庫(kù)有依賴(lài)關(guān)系,那么所有相關(guān)有依賴(lài)關(guān)系的庫(kù)都會(huì)被打開(kāi),這些打開(kāi)的庫(kù)稱(chēng)之
為組(group) 。

mode是打開(kāi)方式:

RTLD_LAZY:打開(kāi)動(dòng)態(tài)庫(kù)后只重定位庫(kù)中數(shù)據(jù)地址引用而不重定位而函數(shù)引用,
函數(shù)引用在該函數(shù)要被激活時(shí)才定位,的確LAZY呵呵,但省開(kāi)銷(xiāo);)
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ù)名稱(chēng) 。成功返回重定位后的符號(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

/* 得到函數(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就可以了,比如:

推薦閱讀