? ? ?
目錄
一、靜態庫
(1)靜態庫的優缺點:
(2)Linux下靜態庫的創建和執行
? ? ? ? 1.直接編譯?編輯
2.指定路徑和庫名
3.用LIBRARY_PATH環境變量來配置路徑
二、動態庫
(1)動態庫的優缺點
(2)Linux下動態庫的創建和執行
三、動態庫的動態加載
(1)dlopen
(2)dlsym
(3)dlclose
(4)dlerror
(5)輔助工具
????????在一個大的項目中,通常都是多人協作開發的,會產生許多的.c文件,但是我們就會出現一些問題-----怎么把這些.c文件生成的二進制文件整合成一個可執行程序呢?
? ? ? ? 我們有兩種方法:靜態庫和動態庫
一、靜態庫
(1)靜態庫的優缺點:
優點:
? ? ? ? 1.靜態庫被打包到了應用程序中,運行速度快(因為不需要實時的鏈接庫文件)
? ? ? ? 2.發布的程序不需要提供靜態庫,因為靜態庫的二進制文件已經被打包在了可執行程序中
? ? ? ? 3.保密性好,靜態庫方式是將可執行程序發布出去(不涉及源代碼的發布)
缺點:
????????1.代碼冗長,用戶需要下載很久
? ? ? ? 2.不利于維護和更新(因為代碼已經是固定的了,而動態庫是運行時跳轉到該函數)
(2)Linux下靜態庫的創建和執行
? ? ? ? 1.直接編譯
(用ar打包成靜態庫)(用gcc生成可執行程序)
????????這里紅色圈出來的都是LInux下創建靜態庫的幾個關鍵點,可以看到在沒有.o文件的時候,編譯器是不能夠將main.c變為可執行程序a.out的,必須要依賴于靜態庫libAdd.a
2.指定路徑和庫名
? ? ? ? 如果靜態庫不在同一個目錄下呢?這個時候我們就需要用-l 和-L選項了。
? ? ? ? 其中-l選項后面跟的是靜態庫的庫名(掐頭去尾只保留中間的部分)
? ? ? ? 而-L選項后面跟的是該靜態庫的路徑(比如這里他就在當前目錄下,所以路徑是.)
3.用LIBRARY_PATH環境變量來配置路徑
????????這里要注意一點:我們直接使用是不行的,因為配置的是自定義的環境變量(只有bash可以使用),但是gcc是bash的兒子,所以不能使用,需要將這個環境變量變成全局的才能讓他的兒子使用,于是我們就要用export將其轉換為全局的環境變量。這時候才可以使用
二、動態庫
(1)動態庫的優缺點
優點:
????????1.可執行程序文件體積小,節省空間
? ? ? ? 2.由于是鏈接起來再使用的,便于更新和維護
缺點:
? ? ? ? 1.文件執行的相對速度比較慢
? ? ? ? 2.文件運行需要依賴于動態庫,如果動態庫缺失則不能正常運行? ??????
(可以看到動態庫中沒有把庫中的二進制代碼拷貝到調用處,而是一個跳轉的指針---鏈接器)
(這里的LD_LIBRARY_PATH環境變量是給鏈接器使用的,能在運行時動態鏈接)
(2)Linux下動態庫的創建和執行
? ? ? ? (用gcc打包成動態庫)(用gcc生成可執行程序)
但是動態庫的創建和靜態庫的使用方法是一樣的,都存在三種方式:
1.直接編譯
2.指定路徑和庫名
3.用LIBRARY_PATH來配置路徑
????????如果直接運行a.out這個可執行程序,會出現一個問題:動態庫是在程序執行的時候,由鏈接器去完成函數間的跳轉的,怎么樣讓鏈接器去知道路徑從而找到動態庫呢?
? ? ? ? 我們只需要配置LD_LIBRARY_PATH這個環境變量就可以了,這樣就可以告知鏈接器在執行的時候的動態庫路徑了
我們可以總結一下:
三、動態庫的動態加載
????????
(1)dlopen
? ? ? ? (注意這里如果只給出了文件名,而沒有帶目錄,則會根據LD_LIBRARY_PATH環境變量的值去搜索動態庫)
(2)dlsym
因為他的返回值是void*類型,如果我們需要的函數不是這個類型呢?
則先把這個函數的返回值強轉成我們需要的類型,再賦值給左邊的函數指針
(3)dlclose
(4)dlerror
這個dlerror( )函數就好像我們c語言中的errno,他隨時記錄的是最近一次發生錯誤的原因