Linux庫概念及相關編程(動態庫、靜態庫、環境變量)

分文件編程:

  • 好處:分模塊編程思想,功能和責任劃分清楚便與調試,main函數簡潔,代碼易于閱讀。
  • 編程時頭文件有的是使用<>這個符號括起來的,有的是" "使用的是雙引號,使用尖括號括起來默認從/user/include/下面去找頭文件或者是/user/local/include/下面去找,而使用雙引號是默認從當前文件路徑去找。

一個小栗子(兩個數相加):

  • mainadd.c文件
#include<stdio.h>
#include"addfunc.h"
int main()
{int a,b,sum;printf("input first number:\n");scanf("%d",&a);printf("input second number:\n");scanf("%d",&b);sum=add(a,b);printf("sum is %d\n",sum);return 0;
}
  • addfunc.c文件,這個文件里面主要是函數體,函數的內部代碼在這個文件里面寫。
int add(int number1,int number2)
{int sum;sum=number1+number2;return sum;
}
  • addfunc.h文件代碼,這個文件主要是函數的聲明,addfunc.h這個文件在main函數頭文件里面要被包含。
int add(int number1,int number2);
  • 然后執行指令:gcc mainadd.c addfunc.c -o add進行編譯

首先了解一下gcc編譯器的工作流程:在這里插入圖片描述

Linux靜態庫、動態庫(共享庫)詳解:

  • 在項目開發過程中,經常出現優秀代碼重用現象,又或者提供給第三方功能模塊卻又不想讓其看到源代碼,這些時候,通常的做法是將代碼封裝成庫或者框架,生成的靜態庫要和頭文件同時發布。
  • 靜態庫特點: 靜態庫在程序編譯時會被連接到目標代碼中,程序運行時將不再需要該靜態庫。靜態庫優點: 尋址方便,速度快;庫在鏈接時被打包到可執行文件中,直接發布可執行程序即可以使用;發布程序無需提供靜態庫,因為已在app中,移植方便靜態庫缺點: 靜態庫的代碼被加載到可執行程序中,因此體積過大;如果靜態庫的函數發生改變,必須重新編譯可執行程序;鏈接時完整的拷貝至可執行文件中,被多次使用就有多份冗余的拷貝;更新、部署、發布、比較麻煩。
  • 動態庫特點: 動態庫的代碼是在可執行程序運行時才載入內存的,在編譯過程中僅簡單的引用,因此代碼體積較小,因此在程序運行時還需要動態庫存在。動態庫優點: 節省內存;易于更新,不用重新編譯可執行程序,運行時自動加載;鏈接時不復制,程序運行時由系統動態加載到內存,供程序使用,系統只加載一次,多個程序可以共用,節省內存。動態庫缺點: 延時綁定,速度略慢;發布程序需要提供依賴的動態庫。注意: 動態函數庫和共享函數庫是一個東西(在Linux上叫共享對象庫,文件后綴是.so在windows上叫做動態函數加載庫,文件后綴是.dll)。
  • Linux中命名系統中共享庫的規則:
    在這里插入圖片描述

靜態庫的制作與使用:

  • 命名規則: 靜態庫文件名的命名方式是“libxxx.a”,庫名前加”lib”,后綴用”.a”,“xxx”為靜態庫名。
  • 制作過程: 原材料:源代碼.c 或者 .cpp。
  • 第一步: 將.c文件生成.o,gcc 源代碼.c -c這里是要將功能函數的.c文件生成.o文件。就用上面的那個例子:將addfunc.c生成.o文件。
 gcc addfunc.c -c得到:addfunc.o
  • 第二步; 將.o 打包ar rcs 靜態庫的名字 原材料,原材料就是上面生成的.o文件,靜態庫名字盡量符合靜態庫的命名規則。
 ar rcs libaddfunc.a addfunc.o得到:libaddfunc.a
  • 靜態庫的使用: 當靜態庫制作完成后,此時不再需要addfunc.c這個文件了,將它移除也不會造成任何影響。但是需要addfunc.h這個文件,因為main函數里面有包含這個頭文件。當別人需要你的代碼時只需將.h和.a文件提供給他們即可。靜態庫使用格式:gcc mainadd.c -laddfunc -L ./若直接-l 編譯會報錯,因為-l 會優先從/urs/lib 或 /urs/local/lib 中去找,但我們想讓它優先從當前路徑去找,就要用到-L ./。使用靜態庫時一般去掉lib和后面的.a直接-l+靜態庫的名字即可。
gcc mainadd.c -laddfunc -L ./ -o add
得到:add這個可執行文件

動態庫的生成和使用:

  • 命名規則: 動態庫的命名方式與靜態庫類似,前綴相同,為“lib”,后綴變為“.so”。所以為“libaddfunc.so”
  • 制作指令: gcc -shared -fpic addfunc.c -o libxxx.so 其中 -shared是指定生成動態庫,-fpic的作用是:作用于編譯階段,在生成目標文件時就得使用該選項,以生成位置無關的代碼。
gcc -shared -fpic addfunc.c -o libaddfunc.so
得到: libaddfunc.so
  • 動態庫的使用: 動態庫的使用和靜態庫的使用方法是一樣的,gcc mainadd.c -laddfunc -L ./ -o add其中mainadd.c 是主函數,addfunc是動態庫的名字。
gcc mainadd.c -laddfunc -L ./ -o add
得到:add這個可執行文件
但是./add會報錯,而靜態庫生成的可執行文件卻不會報錯,
原因是動態庫在生成可執行程序時沒有把動態庫包含進去,
是在程序運行過程中臨時由目標調用動態庫,靜態庫則是已經編譯到,目標程序中了。
  • 這時我們就需要將自己制作的動態庫拷貝到/user/lib/下面,因為他默認的會從/user/lib/下面去找動態庫。
sudo cp libaddfunc.so /usr/lib/
//這時候在執行就不會報錯了。
  • 那么如何在程序執行的時候從當前路徑下去找動態庫呢?通過環境變量LD_LIBRARY_PATH指定動態庫搜索路徑,export LD_LIBRARY_PATH="/home/pi/linuxfile/file1"但是這樣的環境變量是臨時的,當退出后還要重新設置環境變量。所以我們可以使用腳本,將export LD_LIBRARY_PATH="/home/pi/linuxfile/file1"放到腳本里面并且添加./add這個可執行文件的名稱,然后chmod +x start.sh給這個腳本添加可執行的權限。
    在這里插入圖片描述
  • 還可以使用du + 庫的名稱計算文件或者可執行程序的大小例如:du add或者du libaddfunc.so
  • 除了上面哪種方法以外,還在網上看到以下兩種方法:第一種方法:gcc + 源文件 + -L 動態庫路徑 + -l動態庫名 + -I頭文件目錄 + -o 可執行文件名
    gcc main.c -L lib -l MyTest -I include -o app 然后./app會報錯:(執行失敗,找不到鏈接庫,沒有給動態鏈接器(ld-linux.so.2)指定好動態庫 libmytest.so 的路徑)第二種方法:gcc + 源文件 + -I頭文件 + libxxx.so + -o 可執行文件名
    gcc main.c -l include lib/libMyTest.so -o app(執行成功,已經指明了動態庫的路徑)
  • 如何解決第一種方法中找不到鏈接庫的問題?
  • 使用命令ldd app可以查看當前的鏈接庫情況。第一種方法
    export LD_LIBRARY_PATH=自定義動態庫的路徑(只能起到臨時作用,關閉終端后失效)LD_LIBRARY_PATH : 指定查找共享庫(動態鏈接庫)時除了默認路徑之外的其他路徑,該路徑在默認路徑之前查找。第二種方法:將上述命令寫入home目錄下的.bashrc文件中,保存后重啟終端生效(永久)第三種方法:直接將動態庫拷貝到user/lib的系統目錄下(強烈不推薦!!)第四種方法:將libmytest.so所在絕對路徑追加入到/etc/ld.so.conf文件,使用sudo ldconfig -v 更新
    在這里插入圖片描述
    進入/etc/ld.so.conf.d這個文件路徑下,新建一個自己的.conf,我這里是mylib.c將動態庫的絕對路徑加進去然后使用sudo ldconfig -v更新,就可以運行可執行文件了。

Linux環境變量詳解:

  • 環境變量的含義: 環境變量一般是指操作系統中指定操作系統運行環境的一些參數。它相當于一個指針,想要查看變量的值,需要加上“$”。
  • 環境變量的分類:作用的范圍: 分在Linux中的變量,可以分為環境變量和本地變量:①環境變量:相當于全局變量,存在于所有的Shell中,具有繼承性;②本地變量:相當于局部變量只存在當前Shell中,本地變量包含環境變量,非環境變量不具有繼承性。 按生存周期分: ①永久:需要修改配置文件,變量永久生效;②暫時:使用export定義,關閉Shell后失效。
  • 環境變量的組織方式: 每個程序都有一張環境表,環境表是一個指針數組,每個指針指向一個以‘\0’結尾的環境字符串。Main函數的第三個參數就是環境表地址。
    在這里插入圖片描述
    常見的環境變量:
  • PATH: 變量指定命令的搜索路徑。

在這里插入圖片描述使用指令echo $PATH:可以查看在當前目錄下PATH的值。它表示在當前目錄下執行的每一條指令的搜索路徑,每個目錄以冒號隔開。當執行一條指令時,系統就會從系統文件中去尋找,找到了就執行;否則不執行。

  • HOME: 該變量指定用戶的主工作目錄,即用戶登錄到Linux系統時,默認的目錄。 這個環境變量一個變量,它的值隨著用戶的不同而不同。
    普通用戶下的主工作目錄
    在這里插入圖片描述sudo -s進入超級用戶權限, 超級用戶下的主工作目錄

  • LOGNAME: 該變量指定顯示用戶的登錄名。
    在這里插入圖片描述

  • HOSTNAME: 該變量指定主機名
    在這里插入圖片描述

  • SHELL: 該變量指定用戶當前使用的解析器。
    在這里插入圖片描述

修改和顯示環境變量的命令 :

  • echo: 該命令用于顯示某個環境變量的值。

  • env : 該命令指定顯示所有的環境變量和值。

  • set: 顯示系統中已經存在的shell變量,以及設置shell變量的新變量值。使用set更改shell特性時,符號"+“和”-"的作用分別是打開和關閉指定的模式。set命令不能夠定義新的shell變量。如果要定義新的變量,可以使用declare命令以變量名=值的格式進行定義即可。

  • 使用declare命令定義一個新的環境變量"mylove",并且將其值設置為"Visual C++",輸入如下命令: declare mylove='Visual C++' #定義新環境變量再使用set命令將新定義的變量輸出為環境變量,輸入如下命令:set -a mylove #設置為環境變量 執行該命令后,將會新添加對應的環境變量。用戶可以使用env命令和grep命令分別顯示和搜索環境變量"mylove",輸入命令如下:env | grep mylove #顯示環境變量值

  • export : 該命令指定設置一個新的環境變量。注意:環境變量一般用英文字母大寫加下劃線表示。在這里插入圖片描述

  • unset : 該命令指定清除環境變量。

在這里插入圖片描述

  • readonly : 該命令用于設置只讀環境變量,將環境變量MY_ENV設置為只讀模式后,就不能在對它進行修改了,直到用戶退出登錄后才失效。
    5、存放環境變量的文件

幾個文件的作用:

  • /etc/profile 該文件的作用是當用戶登錄時獲取系統的環境變量,只獲取一次。
  • /etc/bashrc 當執行完/etc/profile文件后,用戶想打開bash Shell就會讀取該文件。如果想每次打開bash Shell后都執行某些操作,可以在該文件中設置。
  • ~/.bash_profile 每個用戶都可使用該文件輸入專用于自己使用的shell信息。當用戶登錄時,該文件僅僅執行一次,默認情況下,它設置一些環境變量,執行用戶的.bashrc文件。單個用戶此文件的修改只會影響到他以后的每一次登陸系統。因此,可以在這里設置單個用戶的特殊的環境變量或者特殊的操作,那么它在每次登陸的時候都會去獲取這些新的環境變量或者做某些特殊的操作,但是僅僅在登陸時。
  • ~/.bashrc 該文件包含專用于單個人的bash shell的bash信息,當登錄時以及每次打開一個新的shell時,該該文件被讀取。單個用戶此文件的修改會影響到他以后的每一次登陸系統和每一次新開一個bash。因此,可以在這里設置單個用戶的特殊的環境變量或者特殊的操作,那么每次它新登陸系統或者新開一個bash,都會去獲取相應的特殊的環境變量和特殊操作。
  • ~/.bash_logout 當每次退出系統(退出bash shell)時,執行該文件。

環境變量部分參考這篇博文

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/272186.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/272186.shtml
英文地址,請注明出處:http://en.pswp.cn/news/272186.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

復利計算器

import java.util.Scanner;public class Fulijisuan {public static void main(String[] args) {// TODO Auto-generated method stubdouble F0;double singlesum0;double doublesum0;double m0;Scanner scanner new Scanner(System.in);System.out.println("1:復利計算\n…

kali掃描內網ip_Metasploit路由轉發實現內網滲透

利用背景在滲透的過程中常常會遇到這種場景&#xff1a;我們已經通過web滲透拿下一臺內網服務器&#xff0c;為了進一步進行內網滲透&#xff0c;我們會利用“淪陷主機”作為跳板進行進一步的內網滲透&#xff0c;擴大戰果。現在假設的場景是此時我們已經拿下一臺內網服務器的遠…

.NET Core 3.0 中的新變化

譯者&#xff1a;楚人Leo譯文&#xff1a;http://www.cnblogs.com/leolion/p/10585834.html原文&#xff1a;https://msdn.microsoft.com/en-us/magazine/mt848631.aspx.NET Core 3.0 是 .NET Core 平臺的下一主要版本。本文回顧 .NET Core 發展歷史&#xff0c;并展示了它是如…

樹莓派GPIO口的使用(外設相關開發WringPi庫的使用,超聲波、繼電器)

樹莓派的接口&#xff1a; 大而簡單的類別&#xff1a;IO口&#xff0c;input和output是相對于主控芯片來說的&#xff0c;是根據MCU和外設之間的關系將IO口的功能分為output和input。當IO作為input使用時外設有&#xff1a;人體傳感器、煙霧傳感器、火焰傳感器、振動傳感器等…

下拉框+搜索插件

chosen 轉載于:https://www.cnblogs.com/ilikeballs/p/5291983.html

volatile指令重排_有多少人面試栽到Volatile上?面試問題都總結到這兒了

Volatile關鍵字volatile 是Java虛擬機提供的 輕量級 的同步機制.何為 輕量級 呢&#xff0c;這要相對于 synchronized 來說。Volatile有如下三個特點。要搞清楚上面列舉的名詞 可見性 原子性 指令重排 的含義我們需要首先弄清楚JMM(Java內存模型是怎么回事)JMM規定了內存主要劃…

Dubbo核心概念

節點角色規范 節點角色規格Provider提供者公開遠程服務Consumer消費者致電遠程服務Registry注冊表負責服務發現和配置Monitor監視器計算服務調用的數量和耗時Container容器管理服務的生命周期 服務關系 Container負責啟動&#xff0c;加載和運行服務Provider。ProviderRegiste…

良心推薦11款可以稱得上“神器”的Windows工具集合

1、最快文件搜索工具 Everything&#xff1a;當之無愧的最強本地文件搜索神器&#xff0c;搜索任何關鍵詞基本是秒速出現&#xff0c;比Windows自帶的搜索快了太多&#xff0c;電腦文件比較多的人必備&#xff01; 2、專業軟件卸載器 Revo Uninstaller Pro&#xff1a;Windows電…

HDU 2461 Rectangles#容斥原理

http://acm.hdu.edu.cn/showproblem.php?pid2461 題目很簡單&#xff0c;但是由于詢問數M可以很大&#xff0c;所以容易超時&#xff0c;這道題學到了在結構體里面寫函數的方法&#xff0c;這樣子效率更高&#xff0c;否則的話&#xff0c;這道題就TLE了。 根據容斥原理&#…

LD3320語音識別模塊二次開發及與樹莓派間的通訊

實物圖如下&#xff1a; 一般這種模塊的資料廠家都會給&#xff0c;需要的話可以私信我發郵箱&#xff0c;下面介紹該模塊的各種參數。型號&#xff1a;YS-LDV7名稱&#xff1a;一體化語音識別模塊規格&#xff1a;43*29.7MM供電電壓&#xff1a;5V &#xff08;內部工作電壓…

HTTP的長鏈接和短鏈接說明

HTTP的長鏈接和短鏈接實際上是TCP的長連接和短鏈接。首先我們先介紹一下TCP/IP協議組四層模型。其中包括以下&#xff1a; 應用層&#xff1a;HTTP、FTP、DNS、TELNET等協議傳輸層&#xff1a;TCP、UDP網絡層&#xff1a;IP、ARP、RARP、ICMP協議等網絡接口層&#xff1a;是TC…

多生產者_你是生產者還是消費者?這決定了你的層次。

不知道你有沒有注意到&#xff0c;每天乘坐地鐵上下班的時候&#xff0c;大部分人都在刷劇、看視頻、打游戲等等&#xff0c;總之都屬于玩樂。用生產和消費的關系來看的話&#xff0c;其實這一大部分人都屬于消費者&#xff0c;“時間和注意力”是他們用于交換的籌碼&#xff1…

eclipse Android 開發基礎 Activity 窗體 界面

eclipse Android 開發基礎 新建工程 新建布局layout,new Android Activity就相當于窗體Form。 新建Activity自動生成src下同名的java代碼。 public class Tform2activity extends Activity {Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(saved…

8 種常被忽視的 SQL 錯誤用法

來源&#xff1a;http://t.cn/R6UMaA11、LIMIT 語句2、隱式轉換3、關聯更新、刪除4、混合排序5、EXISTS語句6、條件下推7、提前縮小范圍8、中間結果集下推總結sql語句的執行順序&#xff1a;FROM <left_table>ON <join_condition><join_type> JOIN <right…

變頻器按啟動沒反應_起重機軟啟動柜晶閘管損壞維修幾大故障

缺相保護功能&#xff1a;工作時&#xff0c;軟起動器隨時檢測三相線電流的變化&#xff0c;一旦發生斷流&#xff0c;即可作出缺相保護反應。過熱保護功能&#xff1a;通過軟起動器內部熱繼電器檢測晶閘管散熱器的溫度&#xff0c;一旦散熱器溫度超過允許值后自動關斷晶閘管&a…

Redis 的各項功能解決了哪些問題?

作者丨blackheart先看一下Redis是一個什么東西官方簡介解釋到&#xff1a;Redis是一個基于BSD開源的項目&#xff0c;是一個把結構化的數據放在內存中的一個存儲系統&#xff0c;你可以把它作為數據庫&#xff0c;緩存和消息中間件來使用。同時支持strings&#xff0c;lists&am…

python datetime用法_python datetime用法學習筆記

一、主要思路&#xff1a;1.把表示時間的str轉換為datetime對象2.操作datetime對象輸出期望的時間格式二、把表示時間的str轉換為datetime對象語法&#xff1a;datetime.strptime(date_str, format)示例&#xff1a;date_str "2017-06-23 21:08:12"date_obj dateti…

RocketMQ集成SpringBoot

RocketMQ集成SpringBoot RocketMQ總體架構 RocketMQ基本特性

協議(Protocol)與委托代理(Delegate)

協議(Protocol)的作用&#xff1a; 1. 規范接口&#xff0c;用來定義一套公用的接口&#xff1b; 2. 約束或篩選對象。 代理(Delegate)&#xff1a; 它本身是一種設計模式&#xff0c;委托一個對象<遵守協議>去做某件事情&#xff0c;目的是為了降低對象間的耦合度&#…