C語言鏈接庫的用法
庫文件簡單了説就是包含了別人(或者自己)已經寫好的代碼,可以直接調用的其內部函數的文件。庫文件又包含動態庫文件和靜態庫文件。為什麼有靜態庫和動態庫的區別,我簡單的介紹一下我所理解的什麼是靜態庫,什麼又是動態庫。下面是小編為大家帶來的C語言鏈接庫的用法,歡迎閲讀。
0x01 鏈接庫的簡單理解與編譯命令
庫文件簡單了説就是包含了別人(或者自己)已經寫好的`代碼,可以直接調用的其內部函數的文件。庫文件又包含動態庫文件和靜態庫文件。為什麼有靜態庫和動態庫的區別,我簡單的介紹一下我所理解的什麼是靜態庫,什麼又是動態庫。
靜態庫
Linux系統下後綴名為*.a
Windows系統下後綴名為*
調用靜態庫,在編譯器進行編譯過程中,在有需要調用到庫文件內部函數的地方,編譯器會將靜態庫裏的函數實現過程,拷貝到函數調用的地方。在編譯好的程序運行時,不需要依賴庫文件,可以獨立運行。庫文件對代碼複用性很高,容易理解也容易使用,對提高開發速率有很大幫助,不需要自己造輪子。
Linux下生成靜態庫文件命令
$ gcc -c [FileName].c // 生成*.o文件
$ ar -crv [FileName].a [FileName].o // 生成*.a文件
動態庫
Linux系統下文件名格式為lib*.so
Windows系統下後綴名*.dll
上面介紹了靜態庫在編譯過程中,編譯器會將函數實現拷貝到可執行文件中,所以在程序運行時會佔用一定的資源,造成資源浪費,而且在庫文件的版本更新中,一點微小的改動,就需要對整個程序進行重新編譯發佈,在使用者使用過程中,這是得不償失的。而動態庫,則改進了靜態庫的這些缺點。簡單介紹兩個方面:
1、靜態庫在編譯過程中不需要將代碼編譯到可執行程序中,在程序運行時需要調用的時候才加載。解決了在開發程序中使用靜態庫版本更新的問題,使用動態庫不需要將自己編寫的程序重新編譯,更新庫和更新程序是獨立的兩項任務。
2、可以實現庫共享,不同程序的相同功能代碼的實現可以只需要一份庫文件提供調用,比如jpeg圖像編碼功能,很多程序都需要進行圖像處理,簡單的Logo頭像的顯示到複雜的平面設計,不同的軟件可能使用的都是同一份庫文件。
雖然動態庫相對靜態庫優化了很多缺點,但並不是説可以完全不需要靜態庫。在內部開發的時候,兩個同事對同一個項目的不同子功能進行開發,這些功能具有相互聯繫,但是又不希望對外部人員提供引用,在程序發佈時,打包編譯所有的代碼實現都編譯到程序中。
Linux下編譯生成動態庫文件
$ gcc -fPIC -c [FileName].c
$ gcc -shared -o lib[FileName] [FileName].o
也可以一條命令編譯
gcc -fPIC -shared [FileName].c -o lib[Name]
0x02 庫的編程使用
我主要使用簡單的編程實例介紹動態庫的使用,靜態庫的使用方法與之相同。
我所舉的例子中編寫了3份文件
1、libtest.c // 庫函數實現,最終將此文件編譯成庫文件
2、test.h // 測試頭文件,文件內只有一個結構體變量
3、main.c // 測試代碼主函數的實現
ps: test.h頭文件中只提供了一個結構體,庫文件並不提供新的變量類型引用,新的變量一定需要定義
直接呈上代碼
test.h:
/** test.h **/
#ifndef TEST_H
#define TEST_H
typedef struct {
int a;
char b;
}Test_t;
#endif
libtest.c:
/** libtest.c **/
#include
#include
#include "./test.h"
int fun1(int a)
{
return a*2;
}
Test_t *fun2(Test_t a)
{
a.a++;
a.b = 's';
Test_t *b = malloc(sizeof(Test_t));
*b = a;
return b;
}
很簡單的內容,兩個函數,fun1()和fun2()
先編譯庫文件
$ gcc -fpic -shared libtest.c -o
main.c:
/** main.c **/
#include
#include
#include "./test.h"
int main()
{
//struct TEST_T A;
Test_t A;
A.a = 10;
A.b = 'w';
printf("[init] Test.a = %d ", A.a);
printf("[init] Test.b = %c", A.b);
printf("");
printf("[call] fun1() = %d", fun1(A.a));
printf("");
Test_t *B;
B = (Test_t *)fun2(A); // 加強制轉換
printf("[call] fun2().a = %d", B->a);
printf("[call] fun2().b = %c", B->b);
printf("");
free(B);
}
編譯主程序
$ gcc main.c -L./ -ltest -I./ -o main
0x03 測試&結果
wangsansan@ubuntu$ ./main
[init] Test.a = 10 [init] Test.b = w
[call] fun_test() = 20
[call] fun2_test().a = 11
[call] fun2_test().b = s
wangsansan@ubunut$
-
C++跳轉語句之Goto對變量定義的影響詳解
goto語句也稱為無條件轉移語句,以下是為大家分享的C++跳轉語句之Goto對變量定義的影響詳解,供大家參考借鑑,歡迎瀏覽!前言goto語句也稱為無條件轉移語句,其基本形式如下:語句標號由一個有效地標識符和符號";"組成,其中,標識符的命名規則與變量名稱相同,即由字母、數字...
-
2017全國計算機二級《C語言》考試題及答案
在備考複習階段,需通過大量試題練習,加深對考點的理解和掌握。以下是本站小編搜索整理的一份全國計算機二級《C語言》考試題及答案,供參考練習,希望對大家有所幫助!想了解更多相關信息請持續關注我們應屆畢業生考試網!一、選擇題1).我們所寫的每條C語句,經過編譯最...
-
初學C語言的人最常問的幾個問題
C語言是一門通用計算機編程語言,應用廣泛。對於新手來説學習C語言並不是那麼容易,下面是C語言初學者最常問的幾個問題,歡迎閲讀!1.多久能學會編程?這是一個沒有答案的問題。每個人投入的時間、學習效率和基礎都不一樣。如果你每天都拿出大把的時間來學習,那麼兩三...
-
C語言轉義字符和格式控制符參考
導語:字符型常量所表示的值是字符型變量所能包含的值。我們可以用ASCII表達式來表示一個字符型常量,或者用單引號內加反斜槓表示轉義字符。下面是C語言轉義字符和格式控制符參考,歡迎學習:轉義字符參考:a:蜂鳴,響鈴:回退:向後退一格f:換頁:換行,光標到下行行首:回車,光...