国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

C++靜態(tài)庫與動態(tài)庫深入研究

開發(fā) 后端
這次分享的宗旨是——讓大家學會創(chuàng)建與使用靜態(tài)庫、動態(tài)庫,知道靜態(tài)庫與動態(tài)庫的區(qū)別,知道使用的時候如何選擇。這里不深入介紹靜態(tài)庫、動態(tài)庫的底層格式,內(nèi)存布局等,有興趣的同學,推薦一本書《程序員的自我修養(yǎng)——鏈接、裝載與庫》。

這次分享的宗旨是——讓大家學會創(chuàng)建與使用靜態(tài)庫、動態(tài)庫,知道靜態(tài)庫與動態(tài)庫的區(qū)別,知道使用的時候如何選擇。這里不深入介紹靜態(tài)庫、動態(tài)庫的底層格式,內(nèi)存布局等,有興趣的同學,推薦一本書《程序員的自我修養(yǎng)——鏈接、裝載與庫》。

什么是庫

庫是寫好的現(xiàn)有的,成熟的,可以復用的代碼。現(xiàn)實中每個程序都要依賴很多基礎(chǔ)的底層庫,不可能每個人的代碼都從零開始,因此庫的存在意義非同尋常。

本質(zhì)上來說庫是一種可執(zhí)行代碼的二進制形式,可以被操作系統(tǒng)載入內(nèi)存執(zhí)行。庫有兩種:靜態(tài)庫(.a、.lib)和動態(tài)庫(.so、.dll)。

所謂靜態(tài)、動態(tài)是指鏈接。回顧一下,將一個程序編譯成可執(zhí)行程序的步驟:

C++靜態(tài)庫與動態(tài)庫深入研究

靜態(tài)庫

之所以成為【靜態(tài)庫】,是因為在鏈接階段,會將匯編生成的目標文件.o與引用到的庫一起鏈接打包到可執(zhí)行文件中。因此對應的鏈接方式稱為靜態(tài)鏈接。

試想一下,靜態(tài)庫與匯編生成的目標文件一起鏈接為可執(zhí)行文件,那么靜態(tài)庫必定跟.o文件格式相似。其實一個靜態(tài)庫可以簡單看成是一組目標文件(.o/.obj文件)的集合,即很多目標文件經(jīng)過壓縮打包后形成的一個文件。靜態(tài)庫特點總結(jié):

  • 靜態(tài)庫對函數(shù)庫的鏈接是放在編譯時期完成的。

  • 程序在運行時與函數(shù)庫再無瓜葛,移植方便。

  • 浪費空間和資源,因為所有相關(guān)的目標文件與牽涉到的函數(shù)庫被鏈接合成一個可執(zhí)行文件。

下面編寫一些簡單的四則運算C++類,將其編譯成靜態(tài)庫給他人用,頭文件如下所示:

  1. #pragma once 
  2. class StaticMath 
  3. public
  4.     StaticMath(void); 
  5.     ~StaticMath(void); 
  6.  
  7.     static double add(double a, double b);//加法 
  8.     static double sub(double a, double b);//減法 
  9.     static double mul(double a, double b);//乘法 
  10.     static double div(double a, double b);//除法 
  11.  
  12.     void print(); 
  13. }; 

inux下使用ar工具、Windows下vs使用lib.exe,將目標文件壓縮到一起,并且對其進行編號和索引,以便于查找和檢索。一般創(chuàng)建靜態(tài)庫的步驟如圖所示:

#pragma once class StaticMath { public:     StaticMath(void);     ~StaticMath(void);      static double add(double a, double b);//加法     static double sub(double a, double b);//減法     static double mul(double a, double b);//乘法     static double div(double a, double b);//除法      void print(); };

#p#

Linux下創(chuàng)建與使用靜態(tài)庫

Linux靜態(tài)庫命名規(guī)則

Linux靜態(tài)庫命名規(guī)范,必須是”lib[your_library_name].a”:lib為前綴,中間是靜態(tài)庫名,擴展名為.a。

創(chuàng)建靜態(tài)庫(.a)

通過上面的流程可以知道,Linux創(chuàng)建靜態(tài)庫過程如下:

  • 首先,將代碼文件編譯成目標文件.o(StaticMath.o)

g++ -c StaticMath.cpp

注意帶參數(shù)-c,否則直接編譯為可執(zhí)行文件

  • 然后,通過ar工具將目標文件打包成.a靜態(tài)庫文件

ar -crv libstaticmath.a StaticMath.o

生成靜態(tài)庫libstaticmath.a

Linux下創(chuàng)建與使用靜態(tài)庫

大一點的項目會編寫makefile文件(CMake等等工程管理工具)來生成靜態(tài)庫,輸入多個命令太麻煩了。

使用靜態(tài)庫

編寫使用上面創(chuàng)建的靜態(tài)庫的測試代碼:

  1. #include "StaticMath.h" 
  2. #include <iostream> 
  3. using namespace std; 
  4.  
  5. int main(int argc, char* argv[]) 
  6.     double a = 10; 
  7.     double b = 2; 
  8.  
  9.     cout << "a + b = " << StaticMath::add(a, b) << endl; 
  10.     cout << "a - b = " << StaticMath::sub(a, b) << endl; 
  11.     cout << "a * b = " << StaticMath::mul(a, b) << endl; 
  12.     cout << "a / b = " << StaticMath::div(a, b) << endl; 
  13.  
  14.     StaticMath sm; 
  15.     sm.print(); 
  16.  
  17.     system("pause"); 
  18.     return 0; 

Linux下使用靜態(tài)庫,只需要在編譯的時候,指定靜態(tài)庫的搜索路徑(-L選項)、指定靜態(tài)庫名(不需要lib前綴和.a后綴,-l選項)。

# g++ TestStaticLibrary.cpp -L../StaticLibrary -lstaticmath

  • -L:表示要連接的庫所在目錄

  • -l:指定鏈接時需要的動態(tài)庫,編譯器查找動態(tài)連接庫時有隱含的命名規(guī)則,即在給出的名字前面加上lib,后面加上.a或.so來確定庫的名稱。

#p#

Windows下創(chuàng)建與使用靜態(tài)庫

創(chuàng)建靜態(tài)庫(.lib

如果是使用VS命令行生成靜態(tài)庫,也是分兩個步驟來生成程序:

  • 首先,通過使用帶編譯器選項 /c 的 Cl.exe 編譯代碼 (cl /c StaticMath.cpp),創(chuàng)建名為“StaticMath.obj”的目標文件。

  • 然后,使用庫管理器 Lib.exe 鏈接代碼 (lib StaticMath.obj),創(chuàng)建靜態(tài)庫StaticMath.lib。

當然,我們一般不這么用,使用VS工程設置更方便。創(chuàng)建win32控制臺程序時,勾選靜態(tài)庫類型;打開工程“屬性面板”→”配置屬性”→”常規(guī)”,配置類型選擇靜態(tài)庫。

C++靜態(tài)庫與動態(tài)庫深入研究

Build項目即可生成靜態(tài)庫。

使用靜態(tài)庫

測試代碼Linux下面的一樣。有3種使用方法:

方法一:

在VS中使用靜態(tài)庫方法:

  • 工程“屬性面板”→“通用屬性”→“框架和引用”→”添加引用”,將顯示“添加引用”對話框。 “項目”選項卡列出了當前解決方案中的各個項目以及可以引用的所有庫。 在“項目”選項卡中,選擇 StaticLibrary。 單擊“確定”。

C++靜態(tài)庫與動態(tài)庫深入研究

  • 添加StaticMath.h 頭文件目錄,必須修改包含目錄路徑。打開工程“屬性面板”→”配置屬性”→“C/C++”→” 常規(guī)”,在“附加包含目錄”屬性值中,鍵入StaticMath.h 頭文件所在目錄的路徑或瀏覽至該目錄。

C++靜態(tài)庫與動態(tài)庫深入研究

編譯運行OK。

C++靜態(tài)庫與動態(tài)庫深入研究

如果引用的靜態(tài)庫不是在同一解決方案下的子工程,而是使用第三方提供的靜態(tài)庫lib和頭文件,上面的方法設置不了。還有2中方法設置都可行。

方法二:

打開工程“屬性面板”→”配置屬性”→ “鏈接器”→ ”命令行”,輸入靜態(tài)庫的完整路徑即可。

C++靜態(tài)庫與動態(tài)庫深入研究

方法三:

  • “屬性面板”→”配置屬性”→“鏈接器”→”常規(guī)”,附加依賴庫目錄中輸入,靜態(tài)庫所在目錄;

  • “屬性面板”→”配置屬性”→“鏈接器”→”輸入”,附加依賴庫中輸入靜態(tài)庫名StaticLibrary.lib。

C++靜態(tài)庫與動態(tài)庫深入研究

#p#

動態(tài)庫

通過上面的介紹發(fā)現(xiàn)靜態(tài)庫,容易使用和理解,也達到了代碼復用的目的,那為什么還需要動態(tài)庫呢?

為什么還需要動態(tài)庫?

為什么需要動態(tài)庫,其實也是靜態(tài)庫的特點導致。

  • 空間浪費是靜態(tài)庫的一個問題。

動態(tài)庫

 

  • 另一個問題是靜態(tài)庫對程序的更新、部署和發(fā)布頁會帶來麻煩。如果靜態(tài)庫liba.lib更新了,所以使用它的應用程序都需要重新編譯、發(fā)布給用戶(對于玩家來說,可能是一個很小的改動,卻導致整個程序重新下載,全量更新)。

動態(tài)庫在程序編譯時并不會被連接到目標代碼中,而是在程序運行是才被載入。不同的應用程序如果調(diào)用相同的庫,那么在內(nèi)存里只需要有一份該共享庫的實 例,規(guī)避了空間浪費問題。動態(tài)庫在程序運行是才被載入,也解決了靜態(tài)庫對程序的更新、部署和發(fā)布頁會帶來麻煩。用戶只需要更新動態(tài)庫即可,增量更新。 

C++靜態(tài)庫與動態(tài)庫深入研究

動態(tài)庫特點總結(jié):

  • 動態(tài)庫把對一些庫函數(shù)的鏈接載入推遲到程序運行的時期。

  • 可以實現(xiàn)進程之間的資源共享。(因此動態(tài)庫也稱為共享庫)

  • 將一些程序升級變得簡單。

  • 甚至可以真正做到鏈接載入完全由程序員在程序代碼中控制(顯示調(diào)用)。

Window與Linux執(zhí)行文件格式不同,在創(chuàng)建動態(tài)庫的時候有一些差異。

  • 在Windows系統(tǒng)下的執(zhí)行文件格式是PE格式,動態(tài)庫需要一個DllMain函數(shù)做出初始化的入口,通常在導出函數(shù)的聲明時需要有_declspec(dllexport)關(guān)鍵字。

  • Linux下gcc編譯的執(zhí)行文件默認是ELF格式,不需要初始化入口,亦不需要函數(shù)做特別的聲明,編寫比較方便。

與創(chuàng)建靜態(tài)庫不同的是,不需要打包工具(ar、lib.exe),直接使用編譯器即可創(chuàng)建動態(tài)庫。

#p#

Linux下創(chuàng)建與使用動態(tài)庫

linux動態(tài)庫的命名規(guī)則

動態(tài)鏈接庫的名字形式為 libxxx.so,前綴是lib,后綴名為“.so”。

  • 針對于實際庫文件,每個共享庫都有個特殊的名字“soname”。在程序啟動后,程序通過這個名字來告訴動態(tài)加載器該載入哪個共享庫。

  • 在文件系統(tǒng)中,soname僅是一個鏈接到實際動態(tài)庫的鏈接。對于動態(tài)庫而言,每個庫實際上都有另一個名字給編譯器來用。它是一個指向?qū)嶋H庫鏡像文件的鏈接文件(lib+soname+.so)。

創(chuàng)建動態(tài)庫(.so)

編寫四則運算動態(tài)庫代碼:

  1. #pragma once 
  2. class DynamicMath 
  3. public
  4.         DynamicMath(void); 
  5.         ~DynamicMath(void); 
  6.  
  7.         static double add(double a, double b); 
  8.         static double sub(double a, double b); 
  9.         static double mul(double a, double b); 
  10.         static double div(double a, double b); 
  11.         void print(); 
  12. }; 

首先,生成目標文件,此時要加編譯器選項-fpic

g++ -fPIC -c DynamicMath.cpp

-fPIC 創(chuàng)建與地址無關(guān)的編譯程序(pic,position independent code),是為了能夠在多個應用程序間共享。

  • 然后,生成動態(tài)庫,此時要加鏈接器選項-shared

g++ -shared -o libdynmath.so DynamicMath.o

-shared指定生成動態(tài)鏈接庫。

其實上面兩個步驟可以合并為一個命令:

g++ -fPIC -shared -o libdynmath.so DynamicMath.cpp

使用動態(tài)庫

編寫使用動態(tài)庫的測試代碼:

  1. #include "../DynamicLibrary/DynamicMath.h" 
  2.  
  3. #include <iostream> 
  4. using namespace std; 
  5.  
  6. int main(int argc, char* argv[]) 
  7.     double a = 10; 
  8.     double b = 2; 
  9.  
  10.     cout << "a + b = " << DynamicMath::add(a, b) << endl; 
  11.     cout << "a - b = " << DynamicMath::sub(a, b) << endl; 
  12.     cout << "a * b = " << DynamicMath::mul(a, b) << endl; 
  13.     cout << "a / b = " << DynamicMath::div(a, b) << endl; 
  14.  
  15.     DynamicMath dyn; 
  16.     dyn.print(); 
  17.     return 0; 

引用動態(tài)庫編譯成可執(zhí)行文件(跟靜態(tài)庫方式一樣):

g++ TestDynamicLibrary.cpp -L../DynamicLibrary -ldynmath

然后運行:./a.out,發(fā)現(xiàn)竟然報錯了!!!

 

C++靜態(tài)庫與動態(tài)庫深入研究

可能大家會猜測,是因為動態(tài)庫跟測試程序不是一個目錄,那我們驗證下是否如此:

 

C++靜態(tài)庫與動態(tài)庫深入研究

發(fā)現(xiàn)還是報錯!!!那么,在執(zhí)行的時候是如何定位共享庫文件的呢?

1) 當系統(tǒng)加載可執(zhí)行代碼時候,能夠知道其所依賴的庫的名字,但是還需要知道絕對路徑。此時就需要系統(tǒng)動態(tài)載入器(dynamic linker/loader)。

2) 對于elf格式的可執(zhí)行程序,是由ld-linux.so*來完成的,它先后搜索elf文件的 DT_RPATH段—環(huán)境變量LD_LIBRARY_PATH—/etc/ld.so.cache文件列表—/lib/,/usr/lib 目錄找到庫文件后將其載入內(nèi)存。

如何讓系統(tǒng)能夠找到它:

  • 如果安裝在/lib或者/usr/lib下,那么ld默認能夠找到,無需其他操作。

  • 如果安裝在其他目錄,需要將其添加到/etc/ld.so.cache文件中,步驟如下:

  • 1. 編輯/etc/ld.so.conf文件,加入庫文件所在目錄的路徑

  • 2. 運行l(wèi)dconfig ,該命令會重建/etc/ld.so.cache文件

我們將創(chuàng)建的動態(tài)庫復制到/usr/lib下面,然后運行測試程序。

 

C++靜態(tài)庫與動態(tài)庫深入研究

#p#

Windows下創(chuàng)建與使用動態(tài)庫

創(chuàng)建動態(tài)庫(.dll)

與Linux相比,在Windows系統(tǒng)下創(chuàng)建動態(tài)庫要稍微麻煩一些。首先,需要一個DllMain函數(shù)做出初始化的入口(創(chuàng)建win32控制臺程序時,勾選DLL類型會自動生成這個文件): 

  1. // dllmain.cpp : Defines the entry point for the DLL application. 
  2. #include "stdafx.h" 
  3.  
  4. BOOL APIENTRY DllMain( HMODULE hModule, 
  5.                        DWORD  ul_reason_for_call, 
  6.                        LPVOID lpReserved 
  7.                      ) 
  8.     switch (ul_reason_for_call) 
  9.     { 
  10.     case DLL_PROCESS_ATTACH: 
  11.     case DLL_THREAD_ATTACH: 
  12.     case DLL_THREAD_DETACH: 
  13.     case DLL_PROCESS_DETACH: 
  14.         break
  15.     } 
  16.     return TRUE; 

通常在導出函數(shù)的聲明時需要有_declspec(dllexport)關(guān)鍵字:

  1. #pragma once 
  2. class DynamicMath 
  3. public
  4.     __declspec(dllexport) DynamicMath(void); 
  5.     __declspec(dllexport) ~DynamicMath(void); 
  6.  
  7.     static __declspec(dllexportdouble add(double a, double b);//加法 
  8.     static __declspec(dllexportdouble sub(double a, double b);//減法 
  9.     static __declspec(dllexportdouble mul(double a, double b);//乘法 
  10.     static __declspec(dllexportdouble div(double a, double b);//除法 
  11.  
  12.     __declspec(dllexportvoid print(); 
  13. }; 

生成動態(tài)庫需要設置工程屬性,打開工程“屬性面板”→”配置屬性”→”常規(guī)”,配置類型選擇動態(tài)庫。

 

C++靜態(tài)庫與動態(tài)庫深入研究

Build項目即可生成動態(tài)庫。

使用動態(tài)庫

創(chuàng)建win32控制臺測試程序:

  1. #include "stdafx.h" 
  2. #include "DynamicMath.h" 
  3.  
  4. #include <iostream> 
  5. using namespace std; 
  6.  
  7. int _tmain(int argc, _TCHAR* argv[]) 
  8.     double a = 10; 
  9.     double b = 2; 
  10.  
  11.     cout << "a + b = " << DynamicMath::add(a, b) << endl; 
  12.     cout << "a - b = " << DynamicMath::sub(a, b) << endl; 
  13.     cout << "a * b = " << DynamicMath::mul(a, b) << endl; 
  14.     cout << "a / b = " << DynamicMath::div(a, b) << endl; 
  15.  
  16.     DynamicMath dyn; 
  17.     dyn.print(); 
  18.  
  19.     system("pause"); 
  20.     return 0; 

方法一:

  • 工程“屬性面板”→“通用屬性”→“框架和引用”→”添加引用”,將顯示“添加引用”對話框。“項目”選項卡列出了當前解決方案中的各個項目以及可以引用的所有庫。 在“項目”選項卡中,選擇 DynamicLibrary。 單擊“確定”。

 

C++靜態(tài)庫與動態(tài)庫深入研究

  • 添加DynamicMath.h 頭文件目錄,必須修改包含目錄路徑。打開工程“屬性面板”→”配置屬性”→“C/C++”→” 常規(guī)”,在“附加包含目錄”屬性值中,鍵入DynamicMath.h 頭文件所在目錄的路徑或瀏覽至該目錄。

 

C++靜態(tài)庫與動態(tài)庫深入研究

編譯運行OK。

 

C++靜態(tài)庫與動態(tài)庫深入研究

方法二:

  • “屬性面板”→”配置屬性”→“鏈接器”→”常規(guī)”,附加依賴庫目錄中輸入,動態(tài)庫所在目錄;

 

C++靜態(tài)庫與動態(tài)庫深入研究

  • “屬性面板”→”配置屬性”→“鏈接器”→”輸入”,附加依賴庫中輸入動態(tài)庫編譯出來的DynamicLibrary.lib。

 

C++靜態(tài)庫與動態(tài)庫深入研究

這里可能大家有個疑問,動態(tài)庫怎么還有一個DynamicLibrary.lib文件?即無論是靜態(tài)鏈接庫還是動態(tài)鏈接庫,最后都有l(wèi)ib文件,那么兩者區(qū)別是什么呢?其實,兩個是完全不一樣的東西。

 

C++靜態(tài)庫與動態(tài)庫深入研究

StaticLibrary.lib的大小為190KB,DynamicLibrary.lib的大小為3KB,靜態(tài)庫對應的lib文件叫靜態(tài)庫, 動態(tài)庫對應的lib文件叫【導入庫】。實際上靜態(tài)庫本身就包含了實際執(zhí)行代碼、符號表等等,而對于導入庫而言,其實際的執(zhí)行代碼位于動態(tài)庫中,導入庫只包 含了地址符號表等,確保程序找到對應函數(shù)的一些基本地址信息。

#p#

動態(tài)庫的顯式調(diào)用

上面介紹的動態(tài)庫使用方法和靜態(tài)庫類似屬于隱式調(diào)用,編譯的時候指定相應的庫和查找路徑。其實,動態(tài)庫還可以顯式調(diào)用。【在C語言中】,顯示調(diào)用一個動態(tài)庫輕而易舉!

在Linux下顯式調(diào)用動態(tài)庫

#include <dlfcn.h>,提供了下面幾個接口:

  • void * dlopen( const char * pathname, int mode ):函數(shù)以指定模式打開指定的動態(tài)連接庫文件,并返回一個句柄給調(diào)用進程。

  • void* dlsym(void* handle,const char* symbol):dlsym根據(jù)動態(tài)鏈接庫操作句柄(pHandle)與符號(symbol),返回符號對應的地址。使用這個函數(shù)不但可以獲取函數(shù)地址,也可以獲取變量地址。

  • int dlclose (void *handle):dlclose用于關(guān)閉指定句柄的動態(tài)鏈接庫,只有當此動態(tài)鏈接庫的使用計數(shù)為0時,才會真正被系統(tǒng)卸載。

  • const char *dlerror(void):當動態(tài)鏈接庫操作函數(shù)執(zhí)行失敗時,dlerror可以返回出錯信息,返回值為NULL時表示操作函數(shù)執(zhí)行成功。

在Windows下顯式調(diào)用動態(tài)庫

應用程序必須進行函數(shù)調(diào)用以在運行時顯式加載 DLL。為顯式鏈接到 DLL,應用程序必須:

  • 調(diào)用 LoadLibrary(或相似的函數(shù))以加載 DLL 和獲取模塊句柄。

  • 調(diào)用 GetProcAddress,以獲取指向應用程序要調(diào)用的每個導出函數(shù)的函數(shù)指針。由于應用程序是通過指針調(diào)用 DLL 的函數(shù),編譯器不生成外部引用,故無需與導入庫鏈接。

  • 使用完 DLL 后調(diào)用 FreeLibrary。

顯式調(diào)用C++動態(tài)庫注意點

對C++來說,情況稍微復雜。顯式加載一個C++動態(tài)庫的困難一部分是因為C++的name mangling;另一部分是因為沒有提供一個合適的API來裝載類,在C++中,您可能要用到庫中的一個類,而這需要創(chuàng)建該類的一個實例,這不容易做到。

name mangling可以通過extern “C”解決。C++有個特定的關(guān)鍵字用來聲明采用C binding的函數(shù):extern “C” 。用 extern “C”聲明的函數(shù)將使用函數(shù)名作符號名,就像C函數(shù)一樣。因此,只有非成員函數(shù)才能被聲明為extern “C”,并且不能被重載。盡管限制多多,extern “C”函數(shù)還是非常有用,因為它們可以象C函數(shù)一樣被dlopen動態(tài)加載。冠以extern “C”限定符后,并不意味著函數(shù)中無法使用C++代碼了,相反,它仍然是一個完全的C++函數(shù),可以使用任何C++特性和各種類型的參數(shù)。

另外如何從C++動態(tài)庫中獲取類,附上幾篇相關(guān)文章,但我并不建議這么做:

  • 《LoadLibrary調(diào)用DLL中的Class》:http://www.cppblog.com/codejie/archive/2009/09/24/97141.html

  • 《C++ dlopen mini HOWTO》:http://blog.csdn.net/denny_233/article/details/7255673

“顯式”使用C++動態(tài)庫中的Class是非常繁瑣和危險的事情,因此能用“隱式”就不要用“顯式”,能靜態(tài)就不要用動態(tài)。

附件:Linux下庫相關(guān)命令

g++(gcc)編譯選項

  • -shared :指定生成動態(tài)鏈接庫。

  • -static :指定生成靜態(tài)鏈接庫。

  • -fPIC :表示編譯為位置獨立的代碼,用于編譯共享庫。目標文件需要創(chuàng)建成位置無關(guān)碼, 念上就是在可執(zhí)行程序裝載它們的時候,它們可以放在可執(zhí)行程序的內(nèi)存里的任何地方。

  • -L. :表示要連接的庫所在的目錄。

  • -l:指定鏈接時需要的動態(tài)庫。編譯器查找動態(tài)連接庫時有隱含的命名規(guī)則,即在給出的名字前面加上lib,后面加上.a/.so來確定庫的名稱。

  • -Wall :生成所有警告信息。

  • -ggdb :此選項將盡可能的生成gdb 的可以使用的調(diào)試信息。

  • -g :編譯器在編譯的時候產(chǎn)生調(diào)試信息。

  • -c :只激活預處理、編譯和匯編,也就是把程序做成目標文件(.o文件) 。

  • -Wl,options :把參數(shù)(options)傳遞給鏈接器ld 。如果options 中間有逗號,就將options分成多個選項,然后傳遞給鏈接程序。

nm命令

有時候可能需要查看一個庫中到底有哪些函數(shù),nm命令可以打印出庫中的涉及到的所有符號。庫既可以是靜態(tài)的也可以是動態(tài)的。nm列出的符號有很多,常見的有三種:

  • 一種是在庫中被調(diào)用,但并沒有在庫中定義(表明需要其他庫支持),用U表示;

  • 一種是庫中定義的函數(shù),用T表示,這是最常見的;

  • 一種是所謂的弱態(tài)”符號,它們雖然在庫中被定義,但是可能被其他庫中的同名符號覆蓋,用W表示。

$nm libhello.h

ldd命令

ldd命令可以查看一個可執(zhí)行程序依賴的共享庫,例如我們編寫的四則運算動態(tài)庫依賴下面這些庫:

 

C++靜態(tài)庫與動態(tài)庫深入研究

總結(jié)

二者的不同點在于代碼被載入的時刻不同。

  • 靜態(tài)庫在程序編譯時會被連接到目標代碼中,程序運行時將不再需要該靜態(tài)庫,因此體積較大。

  • 動態(tài)庫在程序編譯時并不會被連接到目標代碼中,而是在程序運行是才被載入,因此在程序運行時還需要動態(tài)庫存在,因此代碼體積較小。

動態(tài)庫的好處是,不同的應用程序如果調(diào)用相同的庫,那么在內(nèi)存里只需要有一份該共享庫的實例。帶來好處的同時,也會有問題!如經(jīng)典的DLL Hell問題,關(guān)于如何規(guī)避動態(tài)庫管理問題,可以自行查找相關(guān)資料。

責任編輯:王雪燕 來源: 吳秦(Tyler)
相關(guān)推薦

2010-08-26 15:48:21

DB2優(yōu)化數(shù)據(jù)庫

2011-12-15 10:43:20

JavaNIO

2017-06-06 11:29:23

Java異常研究與分析

2016-01-12 18:04:55

Java異常研究

2011-06-01 10:58:54

Android Service

2022-05-11 09:03:05

CSS容器文本換行

2023-03-15 15:58:11

Python動態(tài)庫C++

2010-11-23 16:35:59

MySQL刪除多表數(shù)據(jù)

2018-12-24 15:00:58

混合云多云云采用

2010-11-18 17:24:27

Oracle旋轉(zhuǎn)ins

2017-06-09 14:30:31

Openstack N對象模型數(shù)據(jù)庫

2009-10-20 10:17:50

綜合布線系統(tǒng)驗收

2022-04-19 08:28:34

main函數(shù)

2010-06-21 13:07:14

2010-08-03 17:36:55

DB2數(shù)據(jù)庫

2010-11-26 11:57:35

MySQL結(jié)果字符串

2010-05-31 17:45:50

MySQL行鎖

2011-06-09 11:11:35

QT 靜態(tài)庫 動態(tài)庫

2013-01-07 13:38:56

Android開發(fā)布局長度單位

2023-11-03 08:25:28

數(shù)據(jù)結(jié)構(gòu)Java
點贊
收藏

51CTO技術(shù)棧公眾號

91极品美女在线| 亚洲国产视频在线| 国产这里只有精品| 久久的色偷偷| 精品亚洲永久免费精品| a毛片在线观看| 欧美视频自拍偷拍| 久久视频www| 精品国产老师黑色丝袜高跟鞋| 五月婷婷激情久久| www国产精品av| 国产免费观看高清视频| 久久精品国产99| 日韩福利二区| 奇米影视在线99精品| 色女孩综合网| 国产一区在线视频| 日韩精品一区二区在线视频 | 天堂精品久久久久| 一区二区成人av| 亚洲人成777| 久久99久久99精品免观看粉嫩| 亚洲综合网站| 97在线视频观看| 九九免费精品视频在线观看| 国产精品美女久久久久av超清| 精品国产一区探花在线观看| 国产欧美一区二区| 亚洲小说欧美另类社区| 欧洲在线视频一区| 国产成人综合视频| 亚洲成人福利在线观看| 亚洲视频小说图片| 三上悠亚在线观看| 欧美色综合网站| 四虎影院观看视频在线观看| 精品偷拍一区二区三区在线看| 精品无人乱码一区二区三区 | 欧美成人精品在线观看| 精品三级av| 国产在线精品一区免费香蕉| 欧美日韩一卡| 亚洲一区二区在| 久久亚洲欧美国产精品乐播| 少妇网站在线观看| 色诱亚洲精品久久久久久| 男人天堂亚洲天堂| xxxx欧美18另类的高清| 欧美调教在线| 国产乱码精品一区二区三区中文| 看电视剧不卡顿的网站| heyzo国产| 亚洲国产wwwccc36天堂| 中文字幕伦理免费在线视频| 精品国产一区二区三区久久狼黑人 | 欧美综合在线第二页| 一本到12不卡视频在线dvd| 国语精品免费视频| 成人性色生活片| 波多野结衣av在线| 亚洲大胆人体视频| a级日韩大片| 国产精品一区二区三区在线观 | 欧美午夜不卡视频| 国产高清日韩| 国产91精品高潮白浆喷水| 国产精伦一区二区三区| 国产精品入口夜色视频大尺度| 欧美精品啪啪| 色狠狠久久av五月综合| 亚洲午夜精品网| 欧美男男gaytwinkfreevideos| 国产精品你懂得| 亚洲欧美春色| 亚洲视频在线a| 欧美日韩高清一区二区不卡| 欧美一区二区三区婷婷| 91成人免费看| 久久久蜜桃精品| 国产美女av在线| 日韩美女在线观看一区| 国内一区二区视频| 最近中文字幕mv免费高清在线| 亚洲欧洲日韩国产| 亚洲澳门在线| 久久精品香蕉视频| 日韩一区二区三区视频| 小嫩嫩12欧美| 欧美图片激情小说| 欧美日韩三级视频| 免费一区二区| 成人性免费视频| 日韩欧美高清一区| 天天插综合网| 成人漫画网站免费| 中文字幕欧美亚洲| 久久字幕精品一区| 欧美少妇另类| 日本精品久久久久久久| av中文字幕在线不卡| 天堂va在线| 国产精品二区三区| 午夜一区二区三区视频| 超碰在线成人| av在线播放亚洲| 日韩欧美中文一区| 国产精品毛片久久| 好紧好硬好湿我太爽了| 欧美另类老女人| 成人高清视频在线| 免费h视频在线观看| 亚洲欧美三级在线| 国产一区在线看| 岛国精品一区| 97视频在线观看网站| 国产女人水真多18毛片18精品| 欧美亚日韩国产aⅴ精品中极品| 国产精品2023| 九色视频网站入口| 国产精品色婷婷视频| 在线日韩欧美视频| 欧美一区二区视频在线| 欧美日韩国产色视频| 亚洲成在人线免费观看| 成年人网站大全| 久久精视频免费在线久久完整在线看| 麻豆国产精品一区二区三区 | 国产日韩欧美不卡| 国内精品视频| 国产一区视频免费观看| 久久天天躁狠狠躁夜夜躁| 成人av在线影院| 全球最大av网站久久| 青青青在线观看视频| 亚洲精品福利在线观看| 九一久久久久久| 日韩欧美一区二区三区免费观看| 久久免费一级片| 色悠悠久久久久| 国产欧美日韩综合| 伊人成综合网yiren22| 最新中文字幕av专区| 亚洲精品日韩av| 欧美色爱综合网| 日韩av成人高清| 在线最新版中文在线| 青娱乐自拍偷拍| 麻豆成人在线看| 欧美极品少妇xxxxⅹ高跟鞋 | 亚洲欧美综合图区| www.日韩av| 亚洲激情77| 极品白浆推特女神在线观看 | 中文字幕免费精品一区高清| 在线免费视频你懂得| 影音先锋欧美在线| 欧美三级理论片| 色婷婷成人在线| 999在线观看视频| 最新av网址在线观看| 亚洲一区二区精品在线| 久久这里精品国产99丫e6| 国产综合在线观看视频| 国产精品一区二区三区久久久 | 久久精品国产精品亚洲综合| 亚洲女同志freevdieo| 国产免费成人在线| 国产精品久久久久av| 制服丝袜av成人在线看| 成a人片国产精品| 欧美日韩激情在线一区二区三区| 日韩在线资源| 欧美视频在线观看网站| 国产精品一区二区三区成人| 欧美一区二区三区影视| 成人av网站在线观看| 爽成人777777婷婷| av中文在线资源库| 日韩av卡一卡二| 免费日韩av电影| 国内精品久久久久久久久| 在线观看免费视频综合| 本田岬高潮一区二区三区| 97精品在线| 99精品在免费线偷拍| 青青免费在线视频| 黄色大片中文字幕| 都市激情久久久久久久久久久| 伊人青青综合网站| 色噜噜狠狠色综合中国| 97久久超碰国产精品| 亚洲精一区二区三区| 亚洲一区 二区| 福利小视频在线| 日本xxxx高清色视频| 加勒比成人在线| 久久伊人一区| 国产精品一区二区3区| 夜夜躁日日躁狠狠久久88av| 亚洲国产你懂的|