一般應用程式記憶體空間有如下區域:
棧棧儲存了乙個函式呼叫所需要的維護資訊,常被稱為堆疊幀(stack frame)或活動記錄(activate record),一般包含以下幾方面:
堆堆分配演算法:
「段錯誤(segment fault)」 或 「非法操作,該記憶體位址不能 read/write」
典型的非法指標解引用造成的錯誤。當指標指向乙個不允許讀寫的記憶體位址,而程式卻試圖利用指標來讀或寫該位址時,會出現這個錯誤。
普遍原因:
各平台檔案格式
編譯鏈結過程
預編譯(預編譯器處理如 #include、#define 等預編譯指令,生成 .i 或 .ii 檔案)
編譯(編譯器進行詞法分析、語法分析、語義分析、中間**生成、目標**生成、優化,生成 .s 檔案)
彙編(彙編器把彙編碼翻譯成機器碼,生成 .o 檔案)
現在版本 gcc 把預編譯和編譯合成一步,預編譯編譯程式 cc1、彙編器 as、聯結器 ld
msvc 編譯環境,編譯器 cl、聯結器 link、可執行檔案檢視器 dumpbin
目標檔案
可執行檔案(windows 的目標檔案格式.exe
和 linux 的elf
)、動態鏈結庫(windows 的.dll
和 linux 的.so
)、靜態鏈結庫(windows 的.lib
和 linux 的.a
)都是按照可執行檔案格式儲存(windows 按照 pe-coff,linux 按照 elf)
pe 和 elf 都是 coff(common file format)的變種目標檔案儲存結構
鏈結的介面————符號
在鏈結中,目標檔案之間相互拼合實際上是目標檔案之間對位址的引用,即對函式和變數的位址的引用。我們將函式和變數統稱為符號(symbol),函式名或變數名就是符號名(symbol name)。
如下符號表(symbol table)
linux 的共享庫(shared library)
命名 libname.so.x.y.z
x:主版本號,不同主版本號的庫之間不相容,需要重新編譯
y:次版本號,高版本號向後相容低版本號
z:發布版本號,不對介面進行更改,完全相容
路徑大部分包括 linux 在內的開源系統遵循 fhs(file hierarchy standard)的標準,這標準規定了系統檔案如何存放,包括各個目錄結構、組織和作用。
/lib:存放系統最關鍵和最基礎的共享庫,如動態鏈結器、c 語言執行庫、數學庫等
/usr/lib:存放非系統執行時所需要的關鍵性的庫,主要是開發庫
動態鏈結器會在 /lib、/usr/lib 和由 /etc/ld.so.conf 配置檔案指定的,目錄中查詢共享庫
環境變數
ld_library_path:臨時改變某個應用程式的共享庫查詢路徑,而不會影響其他應用程式
ld_preload:指定預先裝載的一些共享庫甚至是目標檔案
so 共享庫的編寫
使用 clion 編寫共享庫
建立乙個名為 mysharedlib 的共享庫
cmakelists.txt
cmake_minimum_required(version 3.10)
project(mysharedlib)
set(cmake_cxx_standard 11)
add_library(mysharedlib shared library.cpp library.h)
library.h
#ifndef mysharedlib_library_h
#define mysharedlib_library_h
// 列印 hello world!
void hello();
// 使用可變模版引數求和
template t sum(t t)
template t sum(t first, types ... rest)
#endif
library.cpp
#include #include "library.h"
void hello()
so 共享庫的使用(被可執行專案呼叫)
使用 clion 呼叫共享庫
建立乙個名為 testsharedlib 的可執行專案
cmakelists.txt
cmakelists.txt
cmake_minimum_required(version 3.10)
project(testsharedlib)
# c++11 編譯
set(cmake_cxx_standard 11)
# 標頭檔案路徑
set(inc_dir /home/xx/code/clion/mysharedlib)
# 庫檔案路徑
set(lib_dir /home/xx/code/clion/mysharedlib/cmake-build-debug)
include_directories($)
link_directories($)
link_libraries(mysharedlib)
add_executable(testsharedlib main.cpp)
# 鏈結 mysharedlib 庫
target_link_libraries(testsharedlib mysharedlib)
main.cpp
#include #include "library.h"
using std::cout;
using std::endl;
int main()
裝載 鏈結與庫
第五部分 windows動態鏈結 1 dll函式和變數必須在檔案顯示是匯入還是匯出,declspec dllexport 匯出,declspec dllimport 匯入.建立dll檔案的時候.c檔案生成.dll,lib,exp檔案,然後用.lib檔案和exe中的.c檔案生成的目標檔案鏈結在一起,生...
鏈結 裝載與庫
鏈結 裝載與庫 在linux下,當我們使用 gcc來編譯 helloword 程式時,只需要 gcc hello.c a.out hello world 其中實際包括4步驟 預處理 prepressinng 編譯 compliation 彙編 assembly 鏈結 linking 1.預編譯 gc...
鏈結 裝載與庫
二 編譯和鏈結 1 預處理過程主要處理那些以 開始的預編譯命令如 include define if 等,但保留 pragma 編譯器指令 因為編譯器要使用它們 另外刪除所有注釋,新增行號和檔名標識。gcc e test.c test.i cpp test.c test.i 2 編譯,生成 s 的彙...