您好,登錄后才能下訂單哦!
一、系統說明
Ubuntu12.04TLS 64位
二、制作靜態庫
(1)編寫需要制作成靜態庫的程序(根據實際情況進行編寫,這里只是一個簡單例子)
//bar.h #ifndef _BAR_H #define _BAR_H void bar(int i); #endif
//bar.c #include <stdio.h> #include <stdlib.h> #include "bar.h" void bar(int i) { printf("Hello! I'm bar, i=%d\n", i); }
//foo.h #ifndef _FOO_H #define _FOO_H void foo(int i); #endif
//foo.c #include <stdio.h> #include <stdlib.h> #include "foo.h" void foo(int i) { printf("Hello! I'm foo, i=%d\n", i); }
(2)制作成靜態庫
gcc -fPIC -c foo.c bar.c ar rcs libstaticlib.a foo.o bar.o
編譯生成foo.o 和 bar.o, 最終生成libstaticlib.a
其中最重要的一個是 -fPIC 參數,如果沒有這個參數,如果是32位系統在制作動態庫的時候沒有問題,但是64位的系統就有問題,制作動態庫的時候將
報錯:
/usr/bin/ld: foo.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC
foo.o: could not read symbols: Bad value
collect2: ld 返回 1
因此將靜態庫制作成64位機器上的動態庫,必須使用-fPIC參數
(3)簡單測試
//main.c #include <stdio.h> #include <stdlib.h> #include "foo.h" #include "bar.h" int main() { int i = 9; int j = 8; foo(i); bar(j); return 0; }
gcc main.c -o test -L. -lstaticlib ./test
結果:
Hello! I'm foo, i=9
Hello! I'm bar, i=8
三、用靜態庫制作成動態庫
(1)將上一步得到的靜態庫解壓,獲得目標文件
ar -x libstaticlib.a
將獲得目標文件foo.o 和 bar.o
(2)將目標文件制作成動態庫
gcc -fPIC -shared -o libsharedlib.so foo.o bar.o
生成動態庫 libsharedlib.so
(3)將動態庫路徑鍵入到加載路徑下
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
這樣做只是暫時的,終端關閉就失效了,想永久生效,修改配置文件
(3)簡單測試
gcc main.c -o test -lsharedlib ./test
結果:
Hello! I'm foo, i=9
Hello! I'm bar, i=8
四、總結
(1)-fPIC 參數不僅在制作動態庫的時候使用,當將靜態庫制作到64位機器上的動態庫時,編譯靜態庫時要使用這個參數
(2)動態庫需要制動加載的路徑,因此需要配置加載路徑
(3)動態庫與靜態庫的一些優缺點
內存中每一個程序都會有一個代碼的拷貝,而動態庫在內存中只有一份
靜態庫編譯的程序可以直接移植到其他地方運行,而動態庫的程序將因找不到鏈接庫將不能執行
靜態庫編譯的程序大小很大
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。