鏈結裝載庫

2021-10-06 10:24:07 字數 3195 閱讀 3560

一般應用程式記憶體空間有如下區域:

棧棧儲存了乙個函式呼叫所需要的維護資訊,常被稱為堆疊幀(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 的彙...