類似
windows
系統中的動態鏈結庫,
linux
中也有相應的共享庫用以支援**的復用。
windows
中為*.dll
,而linux
中為*.so
,我來詳細的告訴你如何在
linux
下編寫動態庫
,以及如何使用它.
在
linux
下編寫動態鏈結庫的步驟
:
1.
編寫庫的標頭檔案和原始檔.
2. 把所有涉及到的原始檔用如下方式編譯 為目標檔案:
g++/gcc -g -c -fpic -o library1.o library1.cpp
g++/gcc -g -c -fpic -o library2.o library2.cpp
......
......
(注釋:
-fpic
指通過這個選項來生成與位置無關的代 碼,可以在任何位址被連線和裝載,
-c指只編譯而不連線原程式)
3. 把所有的目標檔案鏈結為動態庫:
g++/gcc -g -shared -wl,-soname,lib***.so -o lib***.so.1.0.0 library1.o library2.o .... -lc
(注釋:
-lc選項,表示使用
c語言庫,一般都要用到)
4. 建立乙個庫名鏈結
ln -s lib***.so.1.0.0 lib***.so
現在你就可以引用庫了
.下面我分別給出簡單例子告訴你如何動態和靜態使用動態庫:
假如你的應用程式源**叫
testlib.cpp 採用
/如下方式編譯:
g++ -g -o testlib testlib.cpp -ldl
(注釋:
-ldl
選項,表示生成的物件模組需要使用共享 庫)
這個例子告訴你如何動態的呼叫
.so庫
testlib.cpp
#include
#include
#include ...
int main()
dlerror();
//try to load the function in lib
pfunc=(yourfuntiontype(*)(yourfunctionperameterlist))dlsym(handle,"yourfuntionname");
if(dlerror()!=null)
//now you can use the funtion like this
(*pfunc)(yourfuntionperameterlist);
return 0;
}
(注釋:
dlopen()
第乙個參 數:指定共享庫的名稱,將會在下面位置查詢指定的共享庫。
-環境變數
ld_library_path
列出的用分號間隔的所有目錄。
-檔案/etc/ld.so.cache
中找到的庫的列表,用
ldconfig
維護。
-目錄usr/lib。
-目錄/lib。
-當前目 錄。(這裡就是這種情況)
第二個引數: 指定如何開啟共享庫。 -
rtld_now
:將共享庫中的所有函式載入到記憶體 -
rtld_lazy
: 會推後共享庫中的函式的載入操作,直到呼叫
dlsym()
時方載入某函式
dlsym() 呼叫
dlsym
時,利用
dlopen()
返回的共享庫的
phandle
以及函式名稱作為引數,返回要載入函式 的入口位址。
dlerror()
該函式用於檢查呼叫共享庫的相關函式出現的錯誤。 )
特別需要注意的幾點問題:
1. 當你想用
c++寫動態庫的時候
,記住千萬別忘了在標頭檔案裡面加上如下內容
,否則生成的庫在動態呼叫的時候會出問題
!!!!!!!
#ifdef __cplusplus
extern "c"
#endif
2. 當你的庫中包括與
omniorb3
相關的東西的時候
,一定要在
makefile
中加上-d__x86__ -d__osversion=4
/這個例子告訴你如何靜態呼叫
.so庫
首先你得確保你的應用程式能夠找到你的
.so庫
,這可以有幾種方法來實現.
方法一: 1.
你可以把
yourlib.so.1.0.0
和yourlib.so
放到/usr/lib中,
然後執行命令
:ldconfig,
這樣你就可以在你的應用程式中直接呼叫你庫中的函式了
,當然你
得把庫的標頭檔案包含到你的應用程式中 2.
編譯你的應用程式
方法二:
1.你也可以採用在系統中設定環境變數的辦法來實現. 在
root
目錄下:
vi .bash_profile
然後新增
ld_library=/../yourdirincludingyourlib
然後註消一次
,環境變數就生效了
,這樣你就可以在你的應用程式中直接呼叫庫中的函式了
,同樣你得有標頭檔案.
2.編譯你的應用程式
方法三:
你可以直接採用在編譯鏈結的時候告訴系統你的庫在什麼地方 /
假如你的庫中有個函式
:int eat(.....)
那麼採用如下方式呼叫它
#include "yourlib.h"
int main()
是不是很
easy?
對了在靜態呼叫的時候好像不存在上面的"注意
1"的問題
,不過鑑於保險起見
,最好還是按照標準的方式寫
c++標頭檔案吧
,這絕對是個好習慣.
面 通過乙個簡單的例子開始介紹linux標準物件。
我們的標準物件檔案含有乙個函式,不需要宣告export匯出符號,只需要編譯器設定即可。 如下:
設建立乙個tools.**件以及tools.c檔案
/*** tools.h
*/#include "stdio.h"
#include "stdlib.h"
void draw();
void write();
void sign();
void show();
/***tools.c
*/#include "tools.h"
void draw()
void write()
void sign()
void show()
按照如下編譯:
$ gcc -fpic -shared -o libmytools.so tools.c
執行生成乙個libmytools.so檔案,按照linux標準物件的命名慣例,應該在庫名稱之前加上"lib"字首, 儘管不是必須的。編譯開關-fpic代表函式符號可以重定向,-shared代表編譯結果是乙個標準物件。
不同於win32dll,linux標準物件中的所有函式都是直接匯出的,都可以被呼叫程式 所訪問。下面我們編寫呼叫程式:
/*** test.c
*/#include "tools.h"
main()
按照如下gcc編譯:
$ gcc -o test test.c ./libmytools.so
編譯生成test可執行檔案。如上編譯條件的最後一條需要是所呼叫的標準物件檔名,注意必 須含有路徑。如果只是使用libmyso.so,則必須確保這個檔案在可訪問的path下面。本例所使用的檔名"./libmytools.so"是當 前路徑下的,使用了相對路徑。
Linux下編寫簡單的動態鏈結庫
1 linux下編寫動態鏈結庫。通常靜態鏈結庫是編譯的時候和原始檔一起編譯生成可執行檔案的。動態鏈結庫則不是,它是乙個已經編譯好的檔案 靜態則不是 只有當程式執行的時候 但是編譯的時候要將動態鏈結庫的資訊載入進來 它才去找動態鏈結庫拿它想用的一些函式。而且動態鏈結庫可以提高通用性,編寫乙個動態鏈結庫...
Linux下編寫簡單的動態鏈結庫
linux下編寫簡單的動態鏈結庫 1 linux下編寫動態鏈結庫。通常靜態鏈結庫是編譯的時候和原始檔一起編譯生成可執行檔案的。動態鏈結庫則不是,它是乙個已經編譯好的檔案 靜態則不是 只有當程式執行的時候 但是編譯的時候要將動態鏈結庫的資訊載入進來 它才去找動態鏈結庫拿它想用的一些函式。而且動態鏈結庫...
編寫動態鏈結庫
很多時候我們寫 的時候會經常用到某些 段,比方說求兩個或幾個整數的和或者將乙個整形陣列轉化為二叉樹等等。經常使用這些 但是每一次又得重新再寫一遍,次數多了等於就是重複無用勞動了。所以,可以自己動手寫乙個自己的動態鏈結庫,儲存起來。下次用到只需要加上庫就ok了,這樣既方便了自己又對動態鏈結庫本身的工作...