靜態庫與動態庫
靜態函數庫
這類庫的名字一般是libxxx.a,xxx為庫的名字。利用靜態函數庫編譯成的文件比較大,因為整個函數庫的所有數據都會被整合進目標代碼中,他的優點就顯而易見了,即編譯后的執行程序不需要外部的函數庫支持,因為所有使用的函數都已經被編譯進去了。當然這也會成為他的缺點,因為如果靜態函數庫改變了,那么你的程序必須重新編譯。
動態函數庫
這類庫的名字一般是libxxx.M.N.so,同樣的xxx為庫的名字,M是庫的主版本號,N是庫的副版本號。當然也可以不要版本號,但名字必須有。相對於靜態函數庫,動態函數庫在編譯的時候並沒有被編譯進目標代碼中,你的程序執行到相關函數時才調用該函數庫里的相應函數,因此動態函數庫所產生的可執行文件比較小。由於函數庫沒有被整合進你的程序,而是程序運行時動態的申請並調用,所以程序的運行環境中必須提供相應的庫。動態函數庫的改變並不影響你的程序,所以動態函數庫的升級比較方便。linux系統有幾個重要的目錄存放相應的函數庫,如/lib /usr/lib。
1. 生成動態庫並調用
創建文件,用於生成.so
// add.h #include<iostream> int add(int a,int b); //add.cpp #include "add.h" int add(int a, int b) { return a+b; } // hello.h #include<iostream> using namespace std; void hello(); // hello.cpp #include"hello.h" using namespace std; void hello() { cout << "Hello World!!"<<endl; }
創建main.cpp 調用.so文件
#include"add.h"
#include"hello.h"
using namespace std; int main(int argc,char *argv[]) { int a = 20; int b = 30; cout << "a + b = " << add(a,b)<< endl; hello(); return 0; }
******利用cmake生成so文件 並調用*******
首先在當前目錄下創建CMakeLists.txt
# CMakeLists.txt cmake_minimum_required(VERSION 2.8) project(MySharedLib) # C++11 編譯 set(CMAKE_CXX_STANDARD 11) #創建共享庫 add_library(MyTest SHARED add.cpp hello.cpp)
#add_library該指令的主要作用就是將指定的源文件生成鏈接文件 SHARED庫會被動態鏈接(動態鏈接庫)
進入build文件夾下執行cmake .. make 即可生成.so文件
開始測試so文件,在新文件夾下創建include、lib和build文件 創建main.cpp 將add.h hello.h 放入include文件夾 libMyTest.so 放入lib文件夾下,創建CMakeLists.txt
# CMakeLists.txt cmake_minimum_required(VERSION 2.8) #項目名:test project(main) # C++11 編譯 set(CMAKE_CXX_STANDARD 11) # 指定頭文件路徑 set(INC_DIR /home/wangxiaobei/Software/TryMakeSo/test_so/include) # 庫文件路徑 指定靜態和動態文件目錄 set(LIB_DIR /home/wangxiaobei/Software/TryMakeSo/test_so/lib) #指定頭文件目錄 include_directories(${INC_DIR}) #鏈接庫路徑 link_directories(${LIB_DIR}) #鏈接庫,MySharedLib為庫名 link_libraries(MyTest) #生成目標文件 add_executable(c_main main.cpp) # 鏈接 庫文件 MySharedLib 庫 target_link_libraries(c_main MyTest)
進入build 執行cmake .. make 則生成可執行文件c_main
******利用g++生成so 並調用*******
執行g++ add.cpp hello.cpp -fPIC -shared -o libtest.so 將兩個.cpp文件生成 test.so 文件
創建main.cpp 調用.so文件
#include"add.h" #include"hello.h" using namespace std; int main(int argc,char *argv[]) { int a = 20; int b = 30; cout << "a + b = " << add(a,b)<< endl; hello(); return 0; }
g++ main.cpp -L. -ltest -o main
-L參數:指明要鏈接的so庫所在路徑(如-L. 表示當前路徑, -L../so 表示當前路徑的上一層目錄的so子文件夾中)
-l參數:指明要連接的庫的名字,如-ltest 表示要鏈接libtest.so庫
直接運行會報錯 因為沒有鏈接到.so文件,需要在./mian之前告訴so文件的位置 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./libtest
【參考博文】致謝