後台開發核心技術與應用實踐讀書筆記(四)

2021-09-19 15:39:46 字數 3464 閱讀 4862

​ 過程:預處理->編譯->彙編->鏈結

預處理:主要處理那些源**檔案只能夠的以」#」開始的預編譯指令。比如「#include」、「#define」,過濾所有注釋,新增行號,保留#pragma編譯器指令等,最後生成乙個.i檔案

編譯:編譯器掃瞄(詞法分析)、語法分析、語義分析、源**優化、**生成和目標**優化 。生成.s檔案

彙編:經過彙編器彙編得到可重定位目標程式.o檔案

靜態鏈結

​ 對函式庫的鏈結是放在編譯時期完成的是靜態鏈結所有相關的目標檔案與牽涉到的函式庫被鏈結合成 個可執行檔案 程式在執行時,與函式庫再無瓜葛,因為所有需要的函式已複製到相關位置 這些函式庫被稱為靜態庫,通常檔名為「 lib***.a 」的形式。

動態鏈結

​ 除了靜態鏈結,也可以把對 些庫函式的鏈結載入推遲到程式執行時期( runtime ),這

就是動態鏈結庫( dynamic link library )技術 動態庫檔名命名規範和靜態庫檔名命名規

範類似,也是在動態庫名增加字首 lib ,但其擴充套件名為 .so 例如:將建立的動態庫名為

mymath 後,則動態庫檔名就是 libmymath.so。

動態庫的搜尋路徑順序:

編譯目標**時指定的動態庫搜尋路徑;

環境變數 ld_library_path 指定的動態庫搜尋路徑;

配置檔案/etc/ld so.conf 中指定的動態庫搜尋路徑;即只需在在該檔案中追加一行庫所在的完整路徑如 11/root/test/conf/lib 」即可,然後 ldconfig 是修改生效;

預設的動態庫搜尋路徑 lib ;

預設的動態庫搜尋路徑/usr/lib

動態庫與靜態庫重名問題

靜態鏈結庫與動態鏈結庫各自的特點

動態庫有利於程序資源的共享

​ 程式執行時呼叫某個動態鏈結庫函式,作業系統會首先檢視正在執行的程式,看記憶體中是否已經有了此函式的拷貝,如果有就共享,沒有則鏈結載入,雖然會帶來時間開銷,但是減少了空間開銷。而靜態庫每個程式都得將它拷貝到自己的**中

可以將一些程式公升級變得簡單。

​ 靜態庫如果庫發生改變,使用庫的程式要重新編譯。動態庫只要介面沒變,只需要將新生成的動態庫替換原來的即可

可以做到鏈結載入完全由程式設計師在**中控制

有需求才調入的原則

因為動態庫函式必須在執行的時候才被裝載,所以執行過程,用靜態庫速度更快

g++與gcc的區別

兩者都可以編譯c**與c++**

.c檔案,gcc當做c程式,g++當做c++程式。.cpp兩者都當做是c++程式

編譯階段g++會呼叫gcc

編譯可以用 gcc/g++,而鏈結可以用 ++或者 gee-lstde++。gcc不能自動和c++程式使用庫鏈結

externa「c」與兩者並無關係

書寫規則,第一部分為依賴關係,第二部分為生成目標的方法:

target  : prerequisites 

command

command

target也就是乙個目標檔案,可以是.o檔案,也可以是執行檔案,還可以是乙個標籤(label)。

prerequisites就是,要生成那個target所需要的檔案或是目標。

command也就是make需要執行的命令(任意的shell命令)。這裡要注意的是在命令前面要加上乙個tab鍵,不是空格,是按乙個tab鍵按出來的空格

make clean用於清除編譯產生的二進位制檔案,保留原始檔:

clean:

@echo "cleaning project"

-rm main *

.o @echo "clean completed"

在rm命令前面加了乙個小減號的意思就是,也許某些檔案出現問題,但不要管,繼續做後面的事

變數,用$(objects)的方式來使用

$@擴充套件成當前規則的目的檔名;$<擴充套件成依靠列表中的第乙個依靠檔案;$^擴充套件成整個依靠列表(除掉重複檔名)

​ elf是一種二進位制檔案、可執行檔案、目標**、共享庫和核心轉儲的標準檔案格式

elf檔案型別

可重定位的目標檔案

​ 彙編生成的.o檔案。聯結器將器做為目標檔案的輸入,鏈結處理後生成乙個可執行的目標檔案或者乙個可被共享的物件檔案(.so檔案)。

可被執行的目標檔案(.exe)

除了.exe,還有一種是可執行的指令碼(如shell指令碼)檔案。

可被共享的目標檔案

​ 就是動態庫檔案,.so檔案。如果拿前面的靜態庫來生成可執行程式中都會有乙份庫**的拷貝。如果磁碟中儲存這些可執行程式,就會占用額外的磁碟空間。

elf內容

elf檔案主要由檔案頭(elf header)、**段(.text)、資料段(.data)、.bss段、唯讀資料段(.rodata)、段表(section table)、符號表(.symtab)、字串表(.strtab)、重定位表

**段與資料段分開的原因:

1.許可權分別管理。對程序來說,資料段是可讀寫的,指令段是唯讀的。這樣可以防止程式指令被改寫。

2.指令區與資料區的分離有助於提高程式的區域性性,有助於對cpu快取命中率的提高。

3.當系統執行多個改程式的副本的時候,他們對應的指令都是一樣的,此時記憶體只需要保留乙份改程式的指令即可。當然,每個副本程序的資料區域是不一樣的,他們是程序私有的

與elf有關的工具

閱讀 elf 檔案的工具一readelf

獲得二進位制檔案裡符號的工具一nm

減少目標檔案大小的工具一一strip

具體使用見原書

第 1 章 c++常用的程式設計技術

第 2 章 物件導向c++

第 3 章 常用的stl使用

第 4 章 編譯

第 5 章 除錯

第 6 章 tcp協議

第 7 章 網路io模型

第 8 章 網路分析工具

第 9 章 多執行緒

第 10 章 程序

第 11 章 程序間通訊

第 12 章 http協議

後台開發 核心技術與應用實踐

常用類庫 在c 中,臨時物件都是const型別的。可以使用union 聯合 判斷系統是大端 big endian 還是little endian 小端 只能把列舉賦值列舉變數,不能把元素的數值直接賦值列舉變數。共用體以最長的位元組為準,考慮記憶體對齊。結構體以內建型別的最小公倍數對齊。編譯階段 g ...

《後台開發核心技術與應用實踐》(一)

物件導向的c 後台開發核心技術與應用實踐 徐曉鑫 的學習筆記。後台開發技術能力體系,自省!後者先搜尋當前目錄,再搜尋標準頭檔案目錄 1 strlen 是函式,在執行時才能計算。引數必須是字元型指標 char 且必須是以 0 結尾的。當陣列名作為引數傳入時,實際上陣列已經退化為指標了。它的功能是返回字...

後台開發核心技術與應用實踐讀書筆記(一)

include 與 include 後者搜尋當前目錄,在搜尋標準目錄 include與 include 兩者是不同的,前者是c 標準為了與c語言區別開,也為了正確的命名空間,規定的標頭檔案不帶.h 函式的定義 函式過載 c 允許同乙個函式名定義多個函式,但必須引數型別不同與引數個數不同。函式模板 建...