C++中靜態(tài)庫與動態(tài)庫的使用示例
單獨提這個庫,我想我們在coding過程中,可能也會知道一兩個詞,如 標(biāo)準(zhǔn)庫、xx庫等。庫作為一組已編寫好、組織好的、可復(fù)用的資源接口,可以被用于其他程序。很不夸張地說,很多程序都需要依賴一些底層依賴庫,從而支撐它們完成一些基礎(chǔ)工作。
庫主要分為兩種類型:靜態(tài)庫(static library)和動態(tài)庫(shared library)。
靜態(tài)庫
靜態(tài)庫是一個在鏈接過程中采用靜態(tài)鏈接方式鏈接進(jìn)可執(zhí)行文件中的庫文件,在靜態(tài)鏈接方式中,可執(zhí)行文件會拷貝靜態(tài)庫中導(dǎo)出的接口并使其成為它的一部分。在Windows系統(tǒng)中它主要是以.lib為后綴,而在Linux系統(tǒng)中,主要以.a為后綴。
構(gòu)建靜態(tài)庫
項目結(jié)構(gòu)為:
. ├── CMakeLists.txt ├── library.h ├── library.cpp
CMakeLists.txt中的內(nèi)容為:
cmake_minimum_required(VERSION 3.26) project(library) set(CMAKE_CXX_STANDARD 11) add_library(library STATIC library.cpp)
library.h的內(nèi)容為:
#ifndef HELLO_LIB_LIBRARY_H
#define HELLO_LIB_LIBRARY_H
#include <string>
class Test {
public:
explicit Test(std::string str);
std::string getStr() ;
static int getNum() ;
private:
std::string str_;
static int num; // count value
};
void print();
#endif //HELLO_LIB_LIBRARY_Hlibrary.cpp的內(nèi)容為:
#include "library.h"
#include <iostream>
int Test::num = 0; // init
Test::Test(std::string str):str_(std::move(str)) {}
std::string Test::getStr() {
++num;
return str_;
}
int Test::getNum(){
return num;
}采用cmake進(jìn)行構(gòu)建,即可生成對應(yīng)的靜態(tài)庫文件,在Window環(huán)境下將會生成library.lib,而在Linux環(huán)境下將會生成liblibrary.a。
隨后可以在另一個項目中使用它,項目結(jié)構(gòu)為:
.
├── build
├── CMakeLists.txt
├── include
│ └── library.h
├── lib
│ └── library.lib
└── src
└── main.ccCmakeLists.txt的內(nèi)容為:
cmake_minimum_required(VERSION 3.10)
project(lib_test)
set(CMAKE_CXX_STANDARD 11)
include_directories(include)
# 增加鏈接庫的搜索路徑
link_directories(lib)
# 鏈接 library庫
link_libraries(library)
add_executable(${PROJECT_NAME} src/main.cc)而隨后就可以在main.cc中使用它們了:
#include<iostream>
#include"library.h"
int main()
{
Test test("Hello");
std::cout << test.getStr();
std::cout << Test::getNum();
return 0;
}動態(tài)庫
動態(tài)庫也叫做共享庫,在編譯時并不會將所導(dǎo)出的接口拷貝到可執(zhí)行文件中,而是在運行時才會被程序所引用。在Windows系統(tǒng)中它主要是以.dll為后綴,而在Linux系統(tǒng)中,主要以.so為后綴。需要特別注意的是,在MSVC編譯器中,Windows環(huán)境下不僅生成dll后綴文件,還會生成.lib文件,該文件此刻的作用是作為一個導(dǎo)入庫。
構(gòu)建動態(tài)庫
項目結(jié)構(gòu)大體上和上述提到的構(gòu)建的靜態(tài)庫一致,但還需要修改一下CMakeLists以及library.h(針對MSVC編譯器,Linux環(huán)境、MinGW-gcc不用管)。
library.h文件:
#ifndef HELLO_LIB_LIBRARY_H
#define HELLO_LIB_LIBRARY_H
#ifndef EXPORTTING
#define DECLSPEC __declspec(dllimport)
#else
#define DECLSPEC __declspec(dllexport)
#endif // EXPORTTING
#include <string>
class DECLSPEC Test {
public:
explicit Test(std::string str);
std::string getStr() ;
static int getNum() ;
private:
std::string str_;
static int num; // count value
};
void DECLSPEC print();
#endif //HELLO_LIB_LIBRARY_H需要額外的添加__declspec(dllexport)指示這個類/函數(shù)是一個可導(dǎo)出類或函數(shù),以便在dll中導(dǎo)出它的接口同時在lib中有對應(yīng)的符號信息(只有添加了它,MSVC才會生成必需的.lib導(dǎo)入庫)。同時在使用這個庫的項目中引用相關(guān)的頭文件也需要添加__declspec(dllimport)來導(dǎo)入所需的數(shù)據(jù)(沒有這個擴展的話,在一些場景時會出現(xiàn)無法解析符號的錯誤,比如靜態(tài)數(shù)據(jù)的導(dǎo)出等),所以為了方便使用同一個頭文件,在這里采用一個宏來標(biāo)識這兩者的切換時刻。(構(gòu)建庫時導(dǎo)出(__declspec(dllexport)),使用庫時導(dǎo)入(__declspec(dllimport)))
修改CMakeLists文件:
cmake_minimum_required(VERSION 3.26) project(library) set(CMAKE_CXX_STANDARD 11) # SHARED 共享庫 add_library(library SHARED library.cpp) # 加入預(yù)定義宏 EXPORTTING add_definitions(-DEXPORTTING )
在對應(yīng)環(huán)境下采用Cmake工具 構(gòu)建即可得到對應(yīng)環(huán)境下的動態(tài)庫文件,比如Windows環(huán)境下會生成.lib文件和.dll文件,.lib直接和靜態(tài)庫的配置方式一樣,在CMakeLists中修改即可,而將.dll文件直接放置在可執(zhí)行文件同一路徑下,即可隱式鏈接、調(diào)用。而在Linux環(huán)境中,只會生成一個.so文件,其在其他項目的cmake使用配置與靜態(tài)庫配置一致。
前面提到的cmake工具構(gòu)建,構(gòu)建涉及的命令可以歸納為以下步驟:
# 在項目根目錄下執(zhí)行 # 創(chuàng)建build目錄 并進(jìn)行構(gòu)建 cmake -Bbuild # 執(zhí)行 make 即可完成構(gòu)建 # 方式一 cd build make # 方式二 build 是構(gòu)建目錄 lib_test 是構(gòu)建目標(biāo)名 cmake --build build --target lib_test -j 8
它們的不同
- 鏈接時刻不同:靜態(tài)庫會在編譯期完成拷貝與鏈接,而動態(tài)庫會在運行時按需載入。
- 可執(zhí)行文件大小不同:靜態(tài)庫需要整體進(jìn)行拷貝成為可執(zhí)行文件的一部分,而動態(tài)庫無需拷貝多次(拷貝一次,而后其他程序進(jìn)行共享),故對于同一個庫,采用動態(tài)鏈接會使得體積相比靜態(tài)庫更小。
- 執(zhí)行速度不同:靜態(tài)庫在編譯期間已經(jīng)完成鏈接,而動態(tài)庫則會有額外的動態(tài)載入開銷,所以相對來說,靜態(tài)鏈接庫更快。
- 庫更新的影響不同:靜態(tài)庫因為會成為可執(zhí)行文件的一部分,所以其更新的時候會導(dǎo)致可執(zhí)行文件也需要重新編譯,而動態(tài)庫只需更新版本即可(接口不變)。
到此這篇關(guān)于C++中靜態(tài)庫與動態(tài)庫的使用示例的文章就介紹到這了,更多相關(guān)C++ 靜態(tài)庫與動態(tài)庫內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++實現(xiàn)LeetCode(50.求x的n次方)
這篇文章主要介紹了C++實現(xiàn)LeetCode(50.求x的n次方),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07
C++類與對象及構(gòu)造函數(shù)析構(gòu)函數(shù)基礎(chǔ)詳解
這篇文章主要為大家介紹了C++類與對象及構(gòu)造函數(shù)析構(gòu)函數(shù)基礎(chǔ)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04
C++?Boost?MultiArray簡化使用多維數(shù)組庫
Boost是為C++語言標(biāo)準(zhǔn)庫提供擴展的一些C++程序庫的總稱。Boost庫是一個可移植、提供源代碼的C++庫,作為標(biāo)準(zhǔn)庫的后備,是C++標(biāo)準(zhǔn)化進(jìn)程的開發(fā)引擎之一,是為C++語言標(biāo)準(zhǔn)庫提供擴展的一些C++程序庫的總稱2022-11-11

