solaris中有類似windows的DLL有關的函數嗎?

來源:互聯網
上載者:User

如題
呵呵當然有,window那套動東東很多機制都是抄unix的
比如system(32)*.dll是就是仿照unix的/usr/lib/*.so
unix的/usr/lib/*.so就是unix的動態庫(dynamic library)
給程式動態連結用的,反之/usr/lib/*.a是靜態庫,程式編譯
連結時就將相關函數鏈入目標檔案。

實際上泥cc -o yyy yyy.o -lXXX那個XXX就是告訴cc找/usr/lib/libXXX.so..
yyy.o聲明調用了libXXX.so中的函數,連結成功的目標檔案yyy在運行時將動態
調用libXXX.so的函數,至於cc -o yyy yyy.o libxxx.a那就不同了呵呵
cc對-l參數的預設連結方式是動態連結,即只連結符號,不鏈入函數實體。
對連結方式可man ld。

言歸正傳,既然有動態庫,就肯定有與之相關的函數,window有LoadLibrary,
偶solaris有dlopen,就是dynamic library open,window能讓泥做
土版DLL,偶solaris早就能讓泥自己生產.so了呵呵,下面具體說明怎樣調用
動態庫libXXX裡的函數而又不需要在cc中指定-lXXX。

首先是dlopen,格式:

#include
void * dlopen(const char *pathname, int mode);
返回一個void *類型的handle,否則返回NULL。

pathname就是泥所要開啟的動態庫,如果這個庫聲明連結了其它庫,即對其它
庫有依賴關係,那麼所有相關有依賴關係的庫都會被開啟,這些開啟的庫稱之
為組(group)。

mode是開啟檔案:

RTLD_LAZY:開啟動態庫後只重定位庫中資料地址引用而不重定位而函數引用,
函數引用在該函數要被啟用時才定位,的確LAZY呵呵,但省開銷;)
RTLD_NOW: 與上者相比,動態庫一被開啟就重定位所有函數的引用。

RTLD_GLOBAL:開啟動態庫裡的全域符號可以被其它所有庫重定位。
RTLD_LOCAL: 開啟動態庫裡的全域符號只能被同組庫重引用。
RTLD_GROUP: 只有相關組的符號才允許重定位??
RTLD_PARENT:發dlopen調用的對象中的符號對被dlopen對象可見。
RTLD_WORLD: 。。。呵呵太晦澀了我翻譯的我都看不明白;(

總之,一個RTLD_LAZY已經夠用了呵呵;)

然後是得到重定位的資料或函數引用:
#include
void *dlsym(void *handle, const char *name)
意義明顯,handle即dlopen的傳回值,name即泥要引用的在動態庫變數或函
數名稱。成功返回重定位後的符號地址,失敗返回NULL。

最後是關閉動態庫:int dlclose(void *handle),
一看就明白,懶得解釋了;)

下面給一個例子增加感性認識,該例子調用動態庫client.so中的函數
int client_request(char *),該函數返回0或-1並根據不同錯誤設定
字串err_info(也定義在client.so中):

# include
# include
# include

# define TRUE 0
# define FALSE -1

main( )
{
char buf[64];
void *handle; /* 動態庫控制代碼 */
char *err_info; /* 要引用的動態庫中的一個變數 */
int (*client_request)(char *); /* 要引用的一個函數 */

/* 開啟動態庫client.so */
if ((handle = dlopen("client

/* 得到函數名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); /* 從標準輸入讀入命令串 */
if (strcmp(buf, "exit") == TRUE) {
dlclose(handle); /* 關閉動態庫 */
return 0;
}
printf("request:%sn", buf);
client_request(buf); /* 調用動態庫中的函數 */
printf("ask: %sn", err_info); /* 引用動態庫中的變數 */
}

}

最後是編譯問題,怎樣編譯成.so檔案呢?很簡單用ld或者cc -G就可以了,比如:
cc -G yyy.so yyy.o others.o -ldl
如果這個yyy.o有引用了其它動態庫的函數呢?那麼用cc -G ... -l了
比如yyy.o引用了socket函數,那麼
cc -G yyy.so yyy.o others.o -ldl -lsocket即可。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.