C_and_CPP 板


LINE

[轉貼]用gcc 自製 Library 轉自 PTT LinuxDev – 作者: cole945 (躂躂..) 看板: LinuxDev 標題: [心得] 用gcc 自製Library 時間: Sun Nov 5 04:15:45 2006 Library可分成三種,static、shared與dynamically loaded。 1. Static libraries Static 程式庫用於靜態連結,簡單講是把一堆object檔用ar(archiver) 包裝集合起來,檔名以`.a’ 結尾。優點是執行效能通常會比後兩者快, 而且因為是靜態連結,所以不易發生執行時找不到library或版本錯置而 無法執行的問題。缺點則是檔案較大,維護度較低;例如library如果發 現bug需要更新,那麼就必須重新連結執行檔。 1.1 編譯 編譯方式很簡單,先例用`-c’ 編出object 檔,再用ar 包起來即可。 ____ hello.c ____ #include <stdio.h> void hello(){ printf(”Hello “); } ____ world.c ____ #include <stdio.h> void world(){ printf(”world.”); } ____ mylib.h ____ void hello(); void world(); $ gcc -c hello.c world.c /* 編出hello.o 與world.o */ $ ar rcs libmylib.a hello.o world.o /* 包成limylib.a */ 這樣就可以建出一個檔名為libmylib.a 的檔。輸出的檔名其實沒有硬性規定, 但如果想要配合gcc 的’-l’ 參數來連結,一定要以`lib’ 開頭,中間是你要 的library名稱,然後緊接著`.a’ 結尾。 1.2 使用 ____ main.c ____ #include “mylib.h” int main() { hello(); world(); } 使用上就像與一般的object 檔連結沒有差別。 $ gcc main.c libmylib.a 也可以配合gcc 的`-l’ 參數使用 $ gcc main.c -L. -lmylib `[1;33m-L[1;32mdir[m' 參數用來指定要搜尋程式庫的目錄,`.' 表示搜尋現在所在的目 錄。 通常預設會搜/usr/lib 或/lib 等目錄。 `[1;33m-l[1;32mlibrary[m' 參數用來指定要連結的程式庫,'mylib' 表示要與mylib進 行連結 ,他會搜尋library名稱前加`lib'後接`.a'的檔案來連結。 $ ./a.out Hello world. 2. Shared libraries Shared library 會在程式執行起始時才被自動載入。因為程式庫與執行檔 是分離的,所以維護彈性較好。有兩點要注意,shared library是在程式起始 時就要被載入,而不是執行中用到才載入,而且在連結階段需要有該程式庫 才能進行連結。 首先有一些名詞要弄懂,soname、real name與linker name。 soname 用來表示是一個特定library 的名稱,像是libmylib.so.1 。 前面以`lib' 開頭,接著是該library 的名稱,然後是`.so' ,接著 是版號,用來表名他的介面;如果介面改變時,就會增加版號來維護相容度。 real name 是實際放有library程式的檔案名稱,後面會再加上minor 版號與 release 版號,像是libmylib.so.1.0.0 。 一般來說,版號的改變規則是(印象中在APress-Difinitive Guide to GCC中有 提到,但目前手邊沒這本書),最尾碼的release版號用於程式內容的修正, 介面完全沒有改變。中間的minor用於有新增加介面,但相舊介面沒改變,所以 與舊版本相容。最前面的version版號用於原介面有移除或改變,與舊版不相容 時。 linker name是用於連結時的名稱,是不含版號的soname ,如: libmylib.so。 通常linker name與real name是用ln 指到對應的real name ,用來提供 彈性與維護性。 2.1 編譯 shared library的製作過程較複雜。 $ gcc -c -fPIC hello.c world.c 編譯時要加上-fPIC 用來產生position-independent code。也可以用-fpic 參數。(不太清楚差異,只知道-fPIC 較通用於不同平台,但產生的code較大 ,而且編譯速度較慢)。 $ gcc -shared -Wl,-soname,libmylib.so.1 -o libmylib.so.1.0.0 \ hello.o world.o -shared 表示要編譯成shared library -Wl 用於參遞參數給linker,因此-soname與libmylib.so.1會被傳給linker處理。 -soname用來指名soname 為limylib.so.1 library會被輸出成libmylib.so.1.0.0 (也就是real name) 若不指定soname 的話,在編譯結連後的執行檔會以連時的library檔名為 soname,並載入他。否則是載入soname指定的library檔案。 可以利用objdump 來看library 的soname。 $ objdump -p libmylib.so | grep SONAME SONAME libmylib.so.1 若不指名-soname參數的話,則library不會有這個欄位資料。 在編譯後再用ln 來建立soname 與linker name 兩個檔案。 $ ln -s libmylib.so.1.0.0 libmylib.so $ ln -s libmylib.so.1.0.0 libmylib.so.1 2.2 使用 與使用static library 同。 $ gcc main.c libmylib.so 以上直接指定與libmylib.so 連結。 或用 $ gcc main.c -L. -lmylib linker會搜尋libmylib.so 來進行連結。 如果目錄下同時有static與shared library的話,會以shared為主。 使用-static 參數可以避免使用shared連結。 $ gcc main.c -static -L. -lmylib 此時可以用ldd 看編譯出的執行檔與shared程式庫的相依性 $ldd a.out linux-gate.so.1 => (0xffffe000) [1;33mlibmylib.so.1 => not found[m libc.so.6 => /lib/libc.so.6 (0xb7dd6000) /lib/ld-linux.so.2 (0xb7f07000) 輸出結果顯示出該執行檔需要libmylib.so.1 這個shared library。 會顯示not found 因為沒指定該library所在的目錄,所找不到該library。 因為編譯時有指定-soname參數為libmylib.so.1 的關係,所以該執行檔會 載入libmylib.so.1。否則以libmylib.so連結,執行檔則會變成要求載入 libmylib.so $ ./a.out ./a.out: error while loading shared libraries: [1;33mlibmylib.so.1[m: cannot open shared object file: No such file or directory 因為找不到libmylib.so.1 所以無法執行程式。 有幾個方式可以處理。 a. 把libmylib.so.1 安裝到系統的library目錄,如/usr/lib下 b. 設定/etc/ld.so.conf ,加入一個新的library搜尋目錄,並執行ldconfig 更新快取 c. 設定LD_LIBRARY_PATH 環境變數來搜尋library 這個例子是加入目前的目錄來搜尋要載作的library $ LD_LIBRARY_PATH=. ./a.out Hello world. 3. Dynamically loaded libraries Dynamicaaly loaded libraries 才是像windows 所用的DLL ,在使用到 時才載入,編譯連結時不需要相關的library。動態載入庫常被用於像plug-ins 的應用。 3.1 使用方式 動態載入是透過一套dl function來處理。 #include <dlfcn.h> void *dlopen(const char *filename, int flag); 開啟載入filename 指定的library。 void *dlsym(void *handle, const char *symbol); 取得symbol 指定的symbol name在library被載入的記憶體位址。 int dlclose(void *handle); 關閉dlopen開啟的handle。 char *dlerror(void); 傳回最近所發生的錯誤訊息。 ____ dltest.c ____ #include <stdio.h> #include <stdlib.h> #include <dlfcn.h> int main() { void *handle; void (*f)(); char *error; /* 開啟之前所撰寫的libmylib.so 程式庫*/ handle = dlopen("./libmylib.so", RTLD_LAZY); if( !handle ) { fputs( dlerror(), stderr); exit(1); } /* 取得hello function 的address */ f = dlsym(handle, "hello"); if(( error=dlerror())!=NULL) { fputs(error, stderr); exit(1); } /* 呼叫該function */ f(); dlclose(handle); } 編譯時要加上-ldl 參數來與dl library 連結 $ gcc dltest.c -ldl 結果會印出Hello 字串 $ ./a.out Hello 關於dl的詳細內容請參閱man dlopen -- 參考資料: Creating a shared and static library with the gnu compiler [gcc] http://www.adp-gmbh.ch/cpp/gcc/create_lib.html Program Library HOWTO http://tldp.org/HOWTO/Program-Library-HOWTO/index.html APress - Definitive Guide to GCC --



※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 122.116.238.93
1F:推 bizkit:是學長@@ 05/31 13:26
2F:推 cole945:其實我 3. DLL 那段有寫錯@.@ 之前被人糾正的推文不見了.. 05/31 14:13
3F:→ cole945:DLL可以用LoadLibrary()的方式在執行期手動載入.. 05/31 14:14
4F:→ cole945:可是通常會再連結時連結一個import library,在使用上就 05/31 14:15
5F:→ cole945:會像一般的static lib甚至一般的function一樣,執行時也 05/31 14:16
6F:→ cole945:會自動載入,比較方便.. 05/31 14:16
7F:→ freesamael:但是轉貼這個並沒有回答到原本的問題阿... 05/31 14:24
8F:→ jtmh:我也覺得很納悶... 05/31 17:58
9F:推 sunneo: 所以還是得從組語下手了 :o 05/31 22:29







like.gif 您可能會有興趣的文章
icon.png[問題/行為] 貓晚上進房間會不會有憋尿問題
icon.pngRe: [閒聊] 選了錯誤的女孩成為魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一張
icon.png[心得] EMS高領長版毛衣.墨小樓MC1002
icon.png[分享] 丹龍隔熱紙GE55+33+22
icon.png[問題] 清洗洗衣機
icon.png[尋物] 窗台下的空間
icon.png[閒聊] 双極の女神1 木魔爵
icon.png[售車] 新竹 1997 march 1297cc 白色 四門
icon.png[討論] 能從照片感受到攝影者心情嗎
icon.png[狂賀] 賀賀賀賀 賀!島村卯月!總選舉NO.1
icon.png[難過] 羨慕白皮膚的女生
icon.png閱讀文章
icon.png[黑特]
icon.png[問題] SBK S1安裝於安全帽位置
icon.png[分享] 舊woo100絕版開箱!!
icon.pngRe: [無言] 關於小包衛生紙
icon.png[開箱] E5-2683V3 RX480Strix 快睿C1 簡單測試
icon.png[心得] 蒼の海賊龍 地獄 執行者16PT
icon.png[售車] 1999年Virage iO 1.8EXi
icon.png[心得] 挑戰33 LV10 獅子座pt solo
icon.png[閒聊] 手把手教你不被桶之新手主購教學
icon.png[分享] Civic Type R 量產版官方照無預警流出
icon.png[售車] Golf 4 2.0 銀色 自排
icon.png[出售] Graco提籃汽座(有底座)2000元誠可議
icon.png[問題] 請問補牙材質掉了還能再補嗎?(台中半年內
icon.png[問題] 44th 單曲 生寫竟然都給重複的啊啊!
icon.png[心得] 華南紅卡/icash 核卡
icon.png[問題] 拔牙矯正這樣正常嗎
icon.png[贈送] 老莫高業 初業 102年版
icon.png[情報] 三大行動支付 本季掀戰火
icon.png[寶寶] 博客來Amos水蠟筆5/1特價五折
icon.pngRe: [心得] 新鮮人一些面試分享
icon.png[心得] 蒼の海賊龍 地獄 麒麟25PT
icon.pngRe: [閒聊] (君の名は。雷慎入) 君名二創漫畫翻譯
icon.pngRe: [閒聊] OGN中場影片:失蹤人口局 (英文字幕)
icon.png[問題] 台灣大哥大4G訊號差
icon.png[出售] [全國]全新千尋侘草LED燈, 水草

請輸入看板名稱,例如:e-shopping站內搜尋

TOP