c 使用靜態庫和直接使用原始碼有什麼區別?

2021-08-26 02:44:06 字數 1880 閱讀 6241

把一些函式封裝成靜態庫使用和直接使用源**的方式使用,關於使用者編譯出來的體積是使用靜態庫的編譯後體積要比直接使用原始碼編譯的大嗎?或者體積沒變化呢?

基本上沒有區別。如果非要說有區別的話,就是你要把另乙個專案的**扔到自己的專案中,沒有經過./configure之類的步驟,一些開關(一般是config.h裡的巨集)沒有開啟,然後導致編譯出來不同。又或者說在別的機器上編譯完的靜態庫搬到自己的機器上,別人的編譯器版本比較新優化得比較好,又或者說別人的編譯器架構和平台根本不同然後不能用。也就這些很顯然的區別了。

為什麼說沒有區別的呢?我們來看看一般多檔案編譯的過程:

編譯器將每乙個原始檔.cpp都編譯成乙個目標檔案.o。目標檔案裡面有符號表,記錄著函式和它所用到的符號、全域性變數等等。

鏈結器將所有的.o鏈結成系統可辨認的二進位制檔案,或者說「映像」。鏈結器將各個函式重新排列(reallocation),然後將沒有用到的函式捨棄。

即便是加入靜態庫仍然沒有什麼區別,因為:靜態庫本身就只不過是.o檔案的乙個打包(archive)。以gcc的ar為例,我們看看靜態庫.a裡面究竟是什麼:

$ ar -t libfltk.a

fl.o

fl_adjuster.o

fl_bitmap.o

fl_browser.o

fl_browser_.o

fl_browser_load.o

fl_box.o

fl_button.o

fl_chart.o

fl_check_browser.o

fl_check_button.o

fl_choice.o

fl_clock.o

fl_color_chooser.o

fl_copy_su***ce.o

fl_counter.o

fl_dial.o

fl_device.o

fl_double_window.o

fl_file_browser.o

fl_file_chooser.o

fl_file_chooser2.o

fl_file_icon.o

fl_file_input.o

fl_group.o

fl_help_view.o

fl_image.o

fl_image_su***ce.o

...

真相就是,裡面就是一大堆的.o。從源**編譯(第一步)也是生成一大堆.o,從靜態庫里解包也是生成一大堆相同的.o,其餘的步驟完全是沒有區別的。換句話說,比如你有乙個libexample.a,它裡面有src1.o和src2.o兩個目標檔案。你在鏈結的時候用ld -lexample開關鏈結乙個靜態庫,和你先用ar -x libexample.a解包,然後用ld src1.o src2.o鏈結是完全一樣的。

沒有用到的符號將會被自動削除,所以跟直接從原始碼編譯相比,也不會對體積有影響。

lib有個問題是編譯環境必須和你程式一致

比如wchar是否內建,c++執行時是多執行緒動態還是多執行緒靜態等,如果編譯的選項不一致,最後會導致鏈結錯誤

源**沒有這種問題,因為可以修改編譯選項

如果說靜態庫唯一的區別的話,就是平台問題,如果你拿著linux下的乙份源**和乙個靜態庫放在windows下編譯鏈結肯定是不行的,乙個是elf乙個是pe格式。但是你拿著乙份兒完整的源**就可以順利的在windows下編譯使用了。

編譯出來沒區別。只是沒法除錯靜態庫里的**而已

工程原始碼 ubuntu18 04使用靜態ip

ubuntu 18.04已經正式發布。後面會有更多小夥伴會遷移到這個系統。所以將這個設定ip的帖子更新了。在ubuntu18.04中,使用 netplan 進行網路管理。而且16.04之前使用的 etc network inte ces也已經不再使用。現在必須使用 etc netplan yam來配...

C 的Socket的使用原始碼

include stdafx.h include include include 一定要包含該標頭檔案 include pragma comment lib,ws2 32.lib void threadmethod socket scoket void threadmethod socket sco...

建立和使用靜態庫 C

建立和使用靜態庫 c 我們將建立的下乙個庫型別是靜態庫 lib 使用靜態庫是重用 的一種絕佳方式。您不必在自己建立的每個程式中重新實現同一例程,而只需對這些例程編寫一次,然後從需要該功能的應用程式引用它們即可。本演練涵蓋以下內容 先決條件 本主題假定您具備 c 語言的基礎知識。從 檔案 選單中,選擇...