亚洲视频二区_亚洲欧洲日本天天堂在线观看_日韩一区二区在线观看_中文字幕不卡一区

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.430618.com 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

大家好,我是阿木實驗室的松溪,今天給大家介紹一下,linux系統中,庫的概念。

一、庫的簡介

什么是庫,庫簡單地說,就是模塊。用于提供不同功能的模塊,比如我們經常會用的ceres庫,eigen庫,pcl庫等等。庫從本質上來說,是一種可以執行代碼的二進制形式,可以被載入到內存中使用,在Liunx系統中,庫以文件的形式存在,并且可以分為動態鏈接庫靜態鏈接庫兩種,簡稱為動態庫和靜態庫。其中,靜態庫文件的后綴為.a,動態庫文件的后綴為.so。無論是動態庫還是靜態庫,它們無非是向調用的人提供變量、函數或者類。

二、庫的區別

靜態庫和動態庫的區別在于:二者代碼被載入的時刻不同。靜態庫在程序編譯的時候會被鏈接到目標代碼中,目標程序運行的時候將不再需要該庫,移植方便,但是體積會變大,浪費空間和資源,因為與之相關的所有文件都會鏈接合成一個可執行文件,導致可執行文件的體積變大。動態庫在程序編譯的時候并不會被鏈接到目標代碼中,而是在程序運行的時候才被載入,因此可執行文件體積較小。

基本上,大部分的庫都是動態庫,比如:eigen,ceres等,這就是我們通常所說的依賴項,如果你的程序中有需要某個庫,而你的環境中沒有這樣的庫,那么在編譯的時候就會出現這樣的錯誤:xxxx.h文件未找到。這就是典型的缺少動態庫的bug。對此,只需要安裝對應的動態庫即可解決。這個問題經常出現在當你clone某一個代碼下來,但是卻沒有這個代碼的運行環境,當你編譯的時候,就會出現上面的報錯。是不是又get到了一個小技巧呢?

三、靜態庫的創建和使用

在Linux系統中創建靜態庫的過程如下:

1. 編輯源文件(.c或.cpp文件)

2. 通過 gcc -c xxx.c 或 g++ -c xxx.cpp 生成目標文件(.o文件)

3. 使用 ar 命令歸檔目標文件,生成靜態庫

4. 配合靜態庫寫一個頭文件,文件里的內容就是提供給調用者使用的函數、變量或者類的聲明。

在實際創建之前,有必要了解一下,ar命令的使用。ar命令不但可以創建靜態庫,也可以修改或提取已有靜態庫中的信息,其基本用法如下:

ar [option] libxxx.a xx1.o xx2.o xx3.o

其中,libxxx.a是生成靜態庫的文件名字,xxx是自己設定的名稱,lib表示該文件是一個庫,所有在Linux下的庫,都遵守這種命名。即libxxx.a或者libxxx.so。xx1.o xx2.o為靜態庫的目標代碼文件,可以有多個。option常見的選項如下:

-c:創建一個庫,無論庫是否存在,都會創建

-s:創建目標文件索引

-r:在庫中插入模塊,如插入的模塊名已經在庫中存在,則將會替換。如果有一個模塊不存在,將會保存,并不會替換其他同名模塊

-t:顯示庫文件中有哪些目標文件。僅僅顯示

-tv:顯示庫文件有哪些目標文件。包括文件名、時間、大小等

-s:顯示靜態庫文件中的索引表

下面將講解如何創建和使用一個靜態庫

新建一個源文件,test.cpp,復制以下代碼:

#include <IOStream>

void show_age(int age) {
 std::cout << "Your age is: " << age << std::endl;
 }

然后輸入命令

g++ -c test.cpp
ar rcs libshowage.a test.o

這樣就生成了一個靜態庫,要想使用,需要編寫另一個源文件,demo.cpp。復制以下代碼

#include <iostream>

extern void show_age(int age);  //聲明要使用的函數

int main(int argc, char** argv) {
  show_age(18);
  std::cout << "Hi" << std::endl;
}

CMakeLists.txt文件

cmake_minimum_required(VERSION 3.0)
project(demo)

add_executable(demo demo.cpp)
target_link_libraries(demo -L.. -lshowage)

其中,-L參數表示從什么地方找這個庫,(..)表示上一級目錄。-l指定具體的庫,其中lib和.a不需要顯示寫出,編譯器會自動去尋找libshowage.a這個文件。這也就是為什么庫命名的時候要以lib開頭。

四、動態庫的創建和使用

在Linux系統中,存放動態庫的路徑一般為/usr/lib。在Linux系統下進行的鏈接,默認是先鏈接動態庫,如果同時存在靜態庫和動態庫,如果不特別指出,將與動態庫鏈接。這樣有助于節省空間。

同理,我們創建一個動態庫,test.cpp。代碼同上,不做改變。只需要修改生成動態庫的命令。該命令如下:

g++ test.cpp -fPIC -shared -o libshowage.so

-shared 表示生成共享庫

-fPIC表明使用地址無關代碼。PIC全稱是Position Independent Code。在Linux系統下編譯共享庫時,必須加上這個參數,否則在鏈接的時候將會報錯。因為共享庫文件可能會被不同的進程加載到不同的位置上,如果共享對象中的指令使用了絕對地址、外部模塊地址等,那么該庫在被加載的時候,就需要修改地址,這樣就不能實現多進程共享一份物理內存。

編寫一個調用該庫的函數,demo.cpp。內容還是不變。CMakeLists.txt也不變。

五、多個文件生成一個動態庫

創建test1.cpp文件,復制以下代碼

#include <iostream>

void show_age_1(int age) {
 std::cout << "This is lib_1: " << age << std::endl;
 }

創建test2.cpp文件,復制以下代碼

#include <iostream>

void show_age_2(int age) {
 std::cout << "This is lib_2: " << age << std::endl;
 }

創建動態庫

g++ test1.cpp test2.cpp -fPIC -shared -o libshowage.so

需要說明的是,多個文件創建動態庫的時候,不能有同名的函數、類、變量的聲明,否則將無法創建,因為就算創建成功以后,當調用的時候,編譯器并不知道該去調用哪一個源文件里面的聲明。

創建 main.cpp 文件,使用這個庫,復制以下代碼

#include <iostream>

//聲明要使用的函數
extern void show_age_1(int age);
extern void show_age_2(int age);

int main(int argc, char** argv) {
  show_age_1(18);
  show_age_2(36);
}

CMakeLists.txt文件如下

cmake_minimum_required(VERSION 3.0)
project(demo)

add_executable(main main.cpp)
target_link_libraries(main -L.. -lshowage)

當我們運行的時候,會發現這樣的錯誤

./main: error while loading shared libraries: libshowage.so: cannot open shared object file: No such file or directory

在編譯的時候,我們告訴了編譯器,在什么地方去尋找該庫,但是在運行的時候,由于該庫是動態庫,其代碼沒有被鏈接到目標代碼中,因此,在運行的時候,會提示找不到該庫。

因此,只需要將動態庫放到默認的路徑上或者告訴其指定路徑即可。

在Linux系統中,一般將庫放在以下三個地方。其中,/lib用于放置系統級別(或者說內核級別)的庫文件,/usr/lib 用于放置程序級別的庫文件,/usr/local/lib 為用戶級別,一般用戶編譯的都放在這里,以及源碼編譯安裝,例如:opencv的源碼編譯。

因此,我們要將自己的庫放在 /usr/local/lib 下,輸入以下命令

sudo cp ~/C++/demo/libshowage.so /usr/local/lib

當我們移動以后,需要輸入以下命令(必須),更新

sudo ldconfig

這樣,當我們再次運行的時候,就不會報錯了。切記,每次有動態庫在上述目錄中發生變動,都需要輸入這個命令更新,否則還是無法識別。

六、通過apt安裝缺少的動態庫

當我們從github上clone代碼的時候,在編譯的時候,經常出現xxx.h文件不存在,或者No such file or directory。其本質上就是你的環境和別人的環境不一致,缺少相應的庫。一般的解決方式是,將該缺少的頭文件復制到百度,查一查這個頭文件是來自哪一個庫。然后打開終端,輸入命令

sudo apt install libxxx-dev

即可

如果是自定義的動態庫,一般在readme文檔中有說明。

同理,當你向開源社區貢獻開源代碼的同時,也請務必告知運行的環境以及所需要的庫。

七、總結

相信通過本文的介紹,讀者對庫有了一個簡單的認識,在以后的工作和學習過程中,遇到類似的問題,也有了解決問題的思路和方法。

 

阿木實驗室致力于為機器人研發提供開源軟硬件工具和課程服務,讓研發更高效!

- End -

技術發展的日新月異,阿木實驗室將緊跟技術的腳步,不斷把機器人行業最新的技術和硬件推薦給大家。看到經過我們培訓的學員在技術上突飛猛進,是我們培訓最大的價值。如果你在機器人行業,就請關注我們的公眾號,我們將持續發布機器人行業最有價值的信息和技術。

分享到:
標簽:Linux
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定