顯然一個是靜態鏈接庫(.a),一個是動態鏈接庫(.so)
聯系和區別
相同點:鏈接庫本身不是最終的執行程序文件,而是為其他執行文件提供服務的程序。如果把最終的執行程序文件比作一個汽車生產廠家,那么鏈接庫就可以理解為零部件提供商 。
不同點:靜態鏈接庫在鏈接階段就直接打包到最終的執行程序文件中,而動態鏈接庫則是在程序運行時去鏈接庫里面找需要的東西。
優缺點:顯然,靜態鏈接的庫文件會導致最終目標程序文件體積膨脹,優點是編譯之后就不受原來靜態庫文件的影響,即使原來的靜態庫被刪除了都沒關系;
而動態鏈接庫可以保證文件體積較小,在升級程序時很方便,但缺點是庫文件和主程序分開,如果庫文件不存在(刪除、移動或重命名等)了,則主程序文件找不到而出現運行時錯誤。
測試
源文件都是一樣的,來個CMakeLists.txt腳本:
cmake_minimum_required(VERSION 3.10) set(projectName xddll) set(targetName xddll) # set the project name project(${projectName} VERSION 0.12 LANGUAGES CXX ) # specify the C++ standard set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED True) include_directories("${PROJECT_SOURCE_DIR}") add_library(${targetName} STATIC dllmain.cpp)
注意最后面的那個add_library里面的STATIC,指導最終編譯的是一個靜態庫。
然后在程序里面調用,沒啥問題,刪除庫文件再執行,沒啥問題,這就不給出詳細的測試了。
如果把最后面的STATIC改為SHARED,編譯鏈接好最終的執行程序,然后再刪除.so文件以后,就會出現問題了:
第一次檢查到了動態鏈接庫,運行也沒問題,但是修改動態鏈接庫的文件名以后,再使用ldd查看,發現 動態鏈接庫掛了,然后運行執行文件,也掛了。
如果分別用靜態鏈接和動態鏈接方式生成最后的可執行文件,查看文件大小:
可以看到動態庫確實會小一些(這個例子里面不太明顯,畢竟這個庫文件本身就很小)