參考:https://blog.csdn.net/weixin_39609623/article/details/82348576
Windows中的obj,lib,dll,exe文件
lib是和dll對應的。lib是靜態鏈接庫的庫文件,dll是動態鏈接庫的庫文件。
1、靜態就是link的時候把里面需要的東西抽取出來安排到你的exe文件中,以后運行你的exe的時候不再需要lib。
2、動態就是exe運行的時候依賴於dll里面提供的功能,沒有這個dll,你的exe無法運行。
Obj文件時編譯成obj文件,是中間文件。lib,dll,exe都算是最終的目標文件,是最終產物。而c/c++屬於源代碼。源代碼和最終目標文件中過渡的就是中間代碼obj,實際上之所以需要中間代碼,是你不可能一次得到目標文件。比如說一個exe需要很多的cpp文件生成。而編譯器一次只能編譯一個cpp文件。這樣編譯器編譯好一個cpp以后會將其編譯成obj,當所有必須要的cpp都編譯成obj以后,再統一link成所需要的exe,應該說缺少任意一個obj都會導致exe的鏈接失敗。
1.obj里存的是編譯后的代碼跟數據,並且有名稱,所以在連接時有時會出現未解決的外部符號的問題。當連成exe后便不存在名稱的概念了,只有地址。lib就是一堆obj的組合。
2.理論上可以連接obj文件來引用其他工程(可以認為一個obj文件等價於編譯生成它的cpp文件,可以引用obj來替換cpp,也可以添加cpp來替換obj ),但實際中通常用lib來實現工程間相互引用。
3.編譯器會默認鏈接一些常用的庫,其它的需要你自己指定(例如GDAL/opencv等)。
lib和DLL的區別
(1)lib是編譯時需要的,dll是運行時需要的。如果要完成源代碼的編譯,有lib就夠了。如果也使動態連接的程序運行起來,有dll就夠了。在開發和調試階段,當然最好都有。
(2) 一般的動態庫程序有lib文件和dll文件。lib文件是必須在編譯期就連接到應用程序中的,而dll文件是運行期才會被調用的。如果有dll文件,那么對應的lib文件一般是一些索引信息,具體的實現在dll文件中。如果只有lib文件,那么這個lib文件是靜態編譯出來的,索引和實現都在其中。 靜態編譯的lib文件有好處:給用戶安裝時就不需要再掛動態庫了。但也有缺點,就是導致應用程序比較大,而且失去了動態庫的靈活性,在版本升級時,同時要發布新的應用程序才行。
(3)在動態庫的情況下,有兩個文件,一個是引入庫(.LIB)文件(實際上也算是一個靜態庫,只是在鏈接時只能把函數在DLL的入口鏈接到exe中,而不像真正靜態鏈接庫那樣將函數體真正鏈接到exe中 ,通過lib進行的動態鏈接實際上也使用了靜態鏈接來實現 ),一個是DLL文件,引入庫文件包含被DLL導出的函數的名稱和位置,DLL包含實際的函數和數據,應用程序使用LIB文件鏈接到所需要使用的DLL文件,庫中的函數和數據並不復制到可執行文件中,因此在應用程序的可執行文件中,存放的不是被調用的函數代碼,而是DLL中所要調用的函數的內存地址,這樣當一個或多個應用程序運行是再把程序代碼和被調用的函數代碼鏈接起來,從而節省了內存資源。從上面的說明可以看出,DLL和.LIB文件必須隨應用程序一起發行,否則應用程序將會產生錯誤。
DLL內的函數分為兩種:
(1)DLL導出函數,可供應用程序調用;
(2)DLL內部函數,只能在DLL程序使用,應用程序無法調用它們
Linux中的.o,.so,.a文件
.o,是目標文件,相當於windows中的.obj文件;
.so 為共享庫,是shared object,用於動態連接的,相當於windows下的dll;
.a為靜態庫,是好多個.o合在一起,用於靜態連接;
.o文件是鏈接文件,.a是靜態庫文件,靠.o文件生成,作為一個庫為外部程序提供函數,接口。
生成.o文件:
gcc -c test.o test.c
生成.a文件:
ar cqs test.a test.o
.o 就相當於windows里的obj文件 ,一個.c或.cpp文件對應一個.o文件
.a 是好多個.o合在一起,用於靜態連接 ,即STATIC mode,多個.a可以鏈接生成一個exe的可執行文件
.so 是shared object,用於動態連接的,和windows的dll差不多,使用時才載入。