源於systemd的例子
先看bus-error.h中的乙個巨集:
#define bus_error_map_elf_register \
__attribute__ ((__section__("bus_error_map"))) \
__attribute__ ((__used__)) \
__attribute__ ((aligned(8)))
意思是將資料定義在bus_error_map段,8位元組對齊,標記為已使用的
bus-error.c中定義了乙個陣列:
bus_error_map_elf_register const sd_bus_error_map bus_standard_errors = ;
test-bus-error.c中定義了兩個陣列:
bus_error_map_elf_register const sd_bus_error_map test_errors = ;
bus_error_map_elf_register const sd_bus_error_map test_errors2 = ;
如果將bus-error.c編譯到靜態庫,然後test-bus-error.c去連線該靜態庫,bus-error.c和test-bus-error.c中定義的bus_error_map段中的資料會合併到同乙個elf的bus_error_map段中,裡面有三個陣列;
如果將bus-error.c編譯到動態庫,然後test-bus-error.c去連線該動態庫,bus-error.c在.so中,有乙個bus_error_map段;test-bus-error.c在.exe中,有另乙個bus_error_map段,裡面只有兩個陣列。
當使用如下**列印陣列時,就會發現動態連線的輸出會少很多(只列印了test-bus-error.c中的兩個陣列):
extern const sd_bus_error_map __start_bus_error_map;
extern const sd_bus_error_map __stop_bus_error_map;
const sd_bus_error_map *m;
m = __start_bus_error_map;
while (m < __stop_bus_error_map)
printf("%s -> %i/%s\n", strna(m->name), m->code, strna(errno_to_name(m->code)));
m ++;
}printf("---------------------------\n");
}
__start_bus_error_map和__stop_bus_error_map分別是段bus_error_map的起始和結尾位址,由gcc負責處理。
靜態庫動態庫
靜態庫動態庫 靜態庫 是在執行程式之前就已經加入到執行 中,成為執行程式的一部分來執行的,字尾名 a 動態庫 是在執行程式啟動時載入到執行 中,字尾名 so 靜態庫和動態庫區別 動態庫編譯速度慢,執行速度快,但是生成的程式體積較大,占用記憶體,然而動態庫較易公升級,就布局而言,動態庫 不易布局,執行...
靜態庫動態庫
我們使用ls l的時候看到的除了看到檔名,還看到檔案的元資料 擁有的許可權 硬鏈結數 檔案所有者 組 大小 檔案最後修改時間 檔名ls l讀取儲存在磁碟上的檔案資訊,然後顯示出來 其實這個資訊除了通過這種方式來讀取,還有乙個sata命令能夠看到更多的資訊 這裡寫描述 上面的執行結果有幾個資訊需要解釋...
靜態庫 動態庫
學習程式設計,要對編譯鏈結過程了然如胸。在鏈結階段,有兩種鏈結方式 靜態鏈結和動態鏈結。兩者最大的區別在於鏈結的時機不一樣,靜態鏈結是在形成可執行程式前,而動態鏈結的進行則是在程式執行時,下面來詳細介紹這兩種鏈結方式。一 靜態鏈結 然後使用ar工具生成a庫,指令如下 ar命令詳細介紹可以參考這篇部落...