1、乙個程式從原始檔編譯生成可執行檔案的步驟:
預編譯 --> 編譯 --> 彙編 --> 鏈結
(1)預編譯,即預處理,主要處理在源**檔案中以「#」開始的預編譯指令,如巨集展開、處理條件編譯指令、處理#include指令等。
(2)編譯過程就是把預處理完的檔案進行一系列詞法分析、語法分析、語義分析以及優化後生成相應的彙編**檔案。
(3)彙編是將彙編**轉變成二進位制檔案。
(4)鏈結將二進位制檔案鏈結成乙個可執行的命令,主要是把分散的資料和**收集並合成乙個單一的可載入並可執行的的檔案。鏈結可以發生在**靜態編譯、程式被載入時以及程式執行時。鏈結過程的主要工作是符號解析和重定位。
2、庫
庫是一組目標檔案的包,就是一些最常用的**編譯成目標檔案後打包存放。而最常見的庫就是執行時庫(runtime library),如c執行庫crt.
庫一般分為兩種:靜態庫(.a 、.lib)動態庫(.so 、.dll )所謂靜態、動態是指鏈結過程。
3、靜態庫與動態庫
區別:
(1)lib是編譯時用到的,dll是執行時用到的。如果要完成源**的編譯,只需要lib;如果要使動態鏈結的程式執行起來,只需要dll。
(2)如果有dll檔案,那麼lib一般是一些索引資訊,記錄了dll中函式的入口和位置,dll中是函式的具體內容;如果只有lib檔案,那麼這個lib檔案是靜態編譯出來的,索引和實現都在其中。使用靜態編譯的lib檔案,在執行程式時不需要再掛動態庫,缺點是導致應用程式比較大,而且失去了動態庫的靈活性,發布新版本時要發布新的應用程式才行。
(3)動態鏈結的情況下,有兩個檔案:乙個是lib檔案,乙個是dll檔案。lib包含被dll匯出的函式名稱和位置,dll包含實際的函式和資料,應用程式使用lib檔案鏈結到dll檔案。在應用程式的可執行檔案中,存放的不是被呼叫的函式**,而是dll中相應函式**的位址,從而節省了記憶體資源。dll和lib檔案必須隨應用程式一起發行,否則應用程式會產生錯誤。如果不想用lib檔案或者沒有lib檔案,可以用win32 api函式loadlibrary、getprocaddress裝載。
------這裡主要講動態庫的優點特性。--------
靜態庫:函式和資料被編譯進乙個二進位制檔案(通常擴充套件名為.lib)。在使用靜態庫的情況下,在編譯鏈結可執行檔案時,鏈結器從庫中複製這些函式和資料並把它們和應用程式的其它模組組合起來建立最終的可執行檔案(.exe檔案)。
在使用動態庫的時候,往往提供兩個檔案:乙個引入庫和乙個dll。引入庫包含被dll匯出的函式和變數的符號名,dll包含實際的函式和資料。在編譯鏈結可執行檔案時,只需要鏈結引入庫,dll中的函式**和資料並不複製到可執行檔案中,在執行的時候,再去載入dll,訪問dll中匯出的函式。
靜態庫有兩個重大缺點:
1)空間浪費
2)靜態鏈結對程式的更新、部署和發布會帶來很多麻煩。一旦程式中有任何模組更新,整個程式就要重新鏈結,發布給使用者。
特點:1)**共享,所有引用該動態庫的可執行目標檔案共享乙份相同的**與資料。
2)程式公升級方便,應用程式不需要重新鏈結新版本的動態庫來公升級,理論上只要簡單地將舊的目標檔案覆蓋掉。
3)在執行時可以動態地選擇載入各種應用程式模組
python呼叫c 動態庫(1)
由於專案中需要使用python語言搭建伺服器呼叫我的目標檢測演算法來實現功能,所以記錄一下自己除錯過程中的歷程,也做個mark。1.準備c 動態庫 ifndef cppde h define cppde h include cppde global.h include include include...
CUDA動態庫封裝以及呼叫
參考 通過將cuda相關計算操作放在庫中,方便在專案中呼叫,省去了每次編譯cu檔案的麻煩,也便於整合到其他平台上。一 封裝cuda動態庫 主要步驟 修改自定義方式 設定cu檔案項型別為cdua cc 新增依賴庫cudart.lib.1 建立乙個動態庫,這裡建的庫是x86的,也可以更改為x64.2 新...
CUDA動態庫封裝以及呼叫
cuda動態庫封裝以及呼叫 參考 通過將cuda相關計算操作放在庫中,方便在專案中呼叫,省去了每次編譯cu檔案的麻煩,也便於整合到其他平台上。一 封裝cuda動態庫 主要步驟 修改自定義方式 設定cu檔案項型別為cdua cc 新增依賴庫cudart.lib.1 建立乙個動態庫,這裡建的庫是x86的...