<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                上一篇文章[帶你玩轉Visual Studio——帶你高效管理代碼](http://blog.csdn.net/luoweifu/article/details/48866717)通過對VisualSVN優秀插件的講解,讓我們掌握了在集成開發環境VS中快捷高效地管理代碼的技能。然而我們開發的程序并不總是直接地生成可執行的軟件,我們可能只是開發某個大型系統的一個組件,也可能是開發某個軟件的內核SDK提供給上層的應用程序調用,在開發的過程中我們也可能會用到第三方的開源庫。那如果將自己的程序編譯成程序庫給調用方用呢?又如何在自己的程序中引用第三方庫呢?這將是這篇文章要講的內容——發布自己的工程庫。 # 什么是程序庫? 庫是寫好的現有的,成熟的,可以復用的代碼。現實中每個程序都要依賴很多基礎的底層庫,不可能每個人的代碼都從零開始,因此庫的存在意義非同尋常。比如你經常使用的STL(Standard Template Library)也是庫,有了STL你才能方便地使用std::string、std::cout這些類。 本質上來說庫是一種可執行代碼的二進制形式,可以被操作系統載入內存,被別的程序調用執行。C++的庫有兩種:靜態庫和動態庫。將一個程序編譯成可執行文件一般經過 預編譯–>編譯–>鏈接 這幾個過程,而靜態庫與動態庫的區別主要體現在鏈接這個過程。 ## 靜態庫: 在鏈接階段,會將編譯的目標文件.obj 與引用到的庫.lib 一起鏈接打包到可執行文件exe(也稱為目標代碼)中,程序運行時將不再需要該靜態庫。 因此最終鏈接成的可執行文件(.exe)**體積較大**。在Windows中一般以.lib為后綴名,在Linux中一般以.a為后綴名。 ## 動態庫: 在鏈接階段,動態庫.dll并沒有真正被連接到目標代碼中,只是將這個動態庫的聲明鏈接到目標代碼中(這樣程序運行時才知道怎樣使用這個動態庫),動態庫.dll依然是獨立存在的,只有在程序運行是才會將.dll載入到內存中被程序調用。因此程序運行時必須要有這個動態庫且放在正確的路徑中。 因此最終鏈接成的可執行文件(.exe)**體積較小**。在Windows中一般以.dll為后綴名,在Linux中一般以.so為后綴名。 ## 靜態庫與動態庫的區別: | 特點 | 靜態庫 | 動態庫 | | --- | --- | --- | | 對函數庫的鏈接時機 | 在編譯的鏈接階段完成的 | 推遲到程序運行的時期 | | 運行過程與庫的關系 | 程序在運行時與靜態庫再無瓜葛 | 程序在運行時與動態庫庫需要一直存在且路徑正確 | | 是否鏈接到可執行文件 | 靜態庫被鏈接合成一個可執行文件 | 動態庫不會被鏈接到可執行文件中 | | 目標文件大小 | 體積較大 | 體積較小 | | 內存占用度 | 占用內存。如果多個程序使用了同一個靜態庫,每一個程序者會包含這個靜態庫 | 節約內存。如果多個程序使用了同一個動態庫,可以實現進程之間的資源共享(因此動態庫也稱為共享庫) | | 程序移植 | 移植方便 | 移植不太方便,需要所有動態庫的頭文件 | | 程序升級 | 程序升級麻煩,需要下載整個程序進行升級 | 程序升級更簡單,只需要升級某個DLL或某個程序,下載一個升級包即可 | | 編譯出的結果文件 | ProjectName.lib | ProjectName.lib+ProjectName.dll, 這里的ProjectName.lib與靜態庫的.lib文件不同,這只是一個導入庫,只包含了地址符號表等,以便調用方的程序能找到對應的函數,真正的庫文件是ProjectName.dll | * * * * * * # 編譯自己的工程庫 假設我們有這樣一個工程,這個工程的作用就是提供一些常用的工具類和方法,然后我們要將這個工程編譯成庫提供給別人使用。 ## 編譯靜態庫 假設我們已經建好工程并寫好了相應的代碼:? ![](https://box.kancloud.cn/2016-01-19_569dd03903d49.jpg)? 工程目錄 ***Utils.h:*** ~~~ //=============================================================== //Summary: // Utils 類, 工具類 //FileName: // Utils.h //Remarks: // ... //Date: // 2015/10/4 //Author: // Administrator(luoweifu@126.com) //=============================================================== #ifndef __UTILS_H__ #define __UTILS_H__ #include <string> #include <strstream> //#include <cstdlib> class Utils { public: Utils(void); ~Utils(void); public: //--------------------------------------------------------------- //function: // WString2String wstring 到 string 的轉換 //Access: // public //Parameter: // [in] const std::wstring & ws - wstring字符串 //Returns: // std::string - string字符串 //Remarks: // 些方法跨平臺,可移植版本 //author: luoweifu //--------------------------------------------------------------- static std::string WString2String(const std::wstring& ws); //--------------------------------------------------------------- //function: // String2WString string 到 wstring 的轉換 //Access: // public //Parameter: // [in] const std::string & s - string 字符串 //Returns: // std::wstring - wstring字符串 //Remarks: // 些方法跨平臺,可移植版本 //author: luoweifu //--------------------------------------------------------------- static std::wstring String2WString(const std::string& s); }; //--------------------------------------------------------------- //function: // ConvertToString 將int轉換成string //Parameter: // [in] int val - 要轉換的變量 //Returns: // std::string - 轉換后的字符串 //Remarks: // ... //author: luoweifu //--------------------------------------------------------------- std::string ConvertToString(int val); #endif //__UTILS_H__ ~~~ 上述聲明的實現參考后面的附錄[Utils.cpp](http://blog.csdn.net/luoweifu/article/details/48895765#t11)。 這里的注釋是通過VAssistX生成的,關于VAssistX的用法可參考前面寫的一篇文章[帶你玩轉Visual Studio——帶你高效開發](http://blog.csdn.net/luoweifu/article/details/48852119)。 要編譯成靜態庫,我們可以這樣設置我們的工程:? 右鍵工程->Properties? ![](https://box.kancloud.cn/2016-01-19_569dd03912474.jpg)? 編譯成靜態庫 然后右鍵Build就可以了,你可以在解決方案下的Debug(實際的情況中一般要編譯成Release版本,設置的方法一樣,這里的內容后一章中再講)目錄下就能看到Utils.lib,這就是編譯出的庫。要將這個庫給別人使用,只要提供這個Utils.lib和這個工程的頭文件就可以。將Utils.h拷貝到D:\ReleaseLibs\StaticLib\Includes,將Utils.lib拷貝到D:\ReleaseLibs\StaticLib\Libs,把D:\ReleaseLibs\StaticLib這個文件提供出去就可以了。靜態庫的使用請看后一小節[使用靜態庫](http://blog.csdn.net/luoweifu/article/details/48895765#t8) ## 編譯動態庫 與靜態庫相比,編譯動態庫要麻煩一些,一般要在導出函數的聲明處加上_declspec(dllexport)關鍵字前綴。? 1.?****Utils.h***的聲明如下 ~~~ //=============================================================== //Summary: // Utils 類, 工具類 //FileName: // Utils.h //Remarks: // ... //Date: // 2015/10/4 //Author: // Administrator(luoweifu@126.com) //=============================================================== #ifndef __UTILS_H__ #define __UTILS_H__ #include <string> #include <strstream> //#include <cstdlib> //=============================================================== //=============================================================== class Utils { public: Utils(void); ~Utils(void); public: //--------------------------------------------------------------- //function: // Max 獲得兩個數中的最大值 //Access: // public //Parameter: // [in] int nValue1 - 第一個數 // [in] int nValue2 - 每二個數 //Returns: // int - 最大值 //Remarks: // ... //author: luoweifu //--------------------------------------------------------------- static int Max(int nValue1, int nValue2); //--------------------------------------------------------------- //function: // Min 獲得兩個數中的最小值 //Access: // public //Parameter: // [in] int nValue1 - 第一個值 // [in] int nValue2 - 第二個值 //Returns: // int - 最小值 //Remarks: // ... //author: luoweifu //--------------------------------------------------------------- static int Min(int nValue1, int nValue2); //--------------------------------------------------------------- //function: // Range 將一值限定在一個范圍內 //Access: // public //Parameter: // [in] int nMin - 最小值 // [in] int nMax - 最大值 //Returns: // int - 返回在限制在該范圍內的一個值 //Remarks: // ... //author: luoweifu //--------------------------------------------------------------- static int Range(int nMin, int nMax, int nValue); }; //--------------------------------------------------------------- //function: // ConvertToInt 將一個常量字符串轉換成int類型數據 //Access: // public //Parameter: // [in] const char * pStr - 常量字符串 //Returns: // int - 轉換成的int值 //Remarks: // ... //author: luoweifu //--------------------------------------------------------------- int ConvertToInt(const char* pStr); #endif //__UTILS_H__ ~~~ 1. 要編譯成動態庫,我們可以這樣設置我們的工程:? 右鍵工程->Properties? ![](https://box.kancloud.cn/2016-01-19_569dd039234fb.jpg) 設置編譯的目標類型 ![](https://box.kancloud.cn/2016-01-19_569dd0393abd8.jpg) 設置預編譯宏 然后右鍵Build就可以了,你可以在解決方案下的Debug(實際的情況中一般要編譯成Release版本,設置的方法一樣,這里的內容后一章中再講)目錄下就能看到Utils.dll和Utils.lib,這就是編譯出的庫。要將這個庫給別人使用,只要提供這個Utils.dll、Utils.lib和這個工程的頭文件就可以。將Utils.h拷貝到D:\ReleaseLibs\DynamicLib\Includes,將Utils.dll和Utils.lib拷貝到D:\ReleaseLibs\DynamicLib\Libs,把D:\ReleaseLibs\DynamicLib這個文件提供出去就可以了。靜態庫的使用請看后一小節[使用動態庫](http://blog.csdn.net/luoweifu/article/details/48895765#t9) 也許你要問為什么編譯出的靜態庫是Utils.lib,編譯出的動態庫也有Utils.lib,這兩個.lib文件是一樣的嗎?? 你比較一下兩個.lib文件的大小就會發現相差很大(靜態庫的lib有235KB,動態庫的lib只有2.7KB),所以肯定不是一樣的啦!**動態庫對應的lib文件叫“導入庫”,導入庫只包含了地址符號表等,確保調用方的程序能找到對應函數的一些基本地址信息,而實際的執行代碼位于DLL文件中。**靜態庫的lib文件本身就包含了實際執行代碼、符號表等。 # 使用導入(第三方)庫 在實際的開發中經常要用第三方提供的庫,如開源庫,或大型系統中合作方提供的組件。如果使用呢?我們就以上面自己制作的庫為例進行講解。假設我們有一個工程TestProject要使用上面自己制作的Utils庫。 ## 使用靜態庫 1. 右鍵工程->Properties,進行如下的設置。? ![](https://box.kancloud.cn/2016-01-19_569dd0394f898.jpg) 設置頭文件所在的路徑 ![](https://box.kancloud.cn/2016-01-19_569dd0396198a.jpg) 設置lib庫所在的路徑 ![](https://box.kancloud.cn/2016-01-19_569dd039759ef.jpg) 設置要導入哪個lib庫 2. 測試代碼如下: ~~~ #include <iostream> #include <tchar.h> #include "Utils.h" int _tmain(int argc, _TCHAR* argv[]) { int nMax = Utils::Max(25, 37); std::cout << nMax << std::endl; int nMin = Utils::Min(10, 44); std::cout << nMin << std::endl; int nValue = Utils::Range(0, 100, 115); std::cout << nValue << std::endl; char* pStr = "1234"; int nValue2 = ConvertToInt(pStr); std::cout << nValue2 << std::endl; return 0; } ~~~ ## 使用動態庫 1. 右鍵TestProject工程->Properties,進行如下的設置。? ![](https://box.kancloud.cn/2016-01-19_569dd0398ec56.jpg) 設置頭文件所在的路徑? ![](https://box.kancloud.cn/2016-01-19_569dd039a32ce.jpg) 設置lib庫所在的路徑? ![](https://box.kancloud.cn/2016-01-19_569dd039c3b41.jpg) 設置要導入哪個導入庫 2. 將Utils.dll放入與TestProject的輸出文件TestProject.exe相同的路徑下。這個很最重,不然會編譯成功會是執行失敗,因為找不到對應的.dll文件。 3. 測試代碼與靜態庫的一樣。 * * * * * * # 附錄 ## Utils.cpp ~~~ #include "Utils.h" Utils::Utils(void) { } Utils::~Utils(void) { } int Utils::Max( int nValue1, int nValue2 ) { return nValue1 > nValue2 ? nValue1 : nValue2; } int Utils::Min( int nValue1, int nValue2 ) { return nValue1 < nValue2 ? nValue1 : nValue2; } int Utils::Range( int nMin, int nMax, int nValue ) { if (nMax < nMin) { int temp = nMin; nMin = nMax; nMax = temp; } if (nValue < nMin) { return nMin; } else if (nValue > nMax) { return nMax; } else { return nValue; } } int ConvertToInt( const char* pStr ) { int val; std::strstream ss; ss << pStr; ss >> val; return val; } ~~~ 參考文章:[C++靜態庫與動態庫](http://www.cnblogs.com/skynet/p/3372855.html)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看