動態庫和靜態庫的理解

来源:http://www.cnblogs.com/yejianyong/archive/2017/07/02/7105234.html
-Advertisement-
Play Games

1.1 庫的概念 在我看來,庫是已經寫好的、成熟的、可復用的代碼。每個程式都需要依賴很多底層庫,不可能每個人的代碼從零開始編寫代碼,因此庫的存在具有非常重要的意義。 在我們的開發的應用中經常有一些公共代碼是需要反覆使用的,就把這些代碼編譯為庫文件。 庫可以簡單看成一組目標文件的集合,將這些目標文件經 ...


1.1 庫的概念

在我看來,庫是已經寫好的、成熟的、可復用的代碼。每個程式都需要依賴很多底層庫,不可能每個人的代碼從零開始編寫代碼,因此庫的存在具有非常重要的意義。

在我們的開發的應用中經常有一些公共代碼是需要反覆使用的,就把這些代碼編譯為庫文件。

庫可以簡單看成一組目標文件的集合,將這些目標文件經過壓縮打包之後形成的一個文件。像在Windows這樣的平臺上,最常用的c語言庫是由集成按開發環境所附帶的運行庫,這些庫一般由編譯廠商提供。

1.2 vs下靜態庫創建和使用

1.2.1 靜態庫的創建

1. 創建一個新項目,在已安裝的模板中選擇“常規”,在右邊的類型下選擇“空項目”,在名稱和解決方案名稱中輸入staticlib。點擊確定。 2.在解決方案資源管理器的頭文件中添加,mylib.h文件,在源文件添加mylib.c文件(即實現文件)。 3.在mylib.h文件中添加如下代碼:
   #ifndef TEST_H    #define TEST_H         int myadd(int a,int b);    #endif   
4.在mylib.c文件中添加如下代碼:
   #include"test.h"    int myadd(int a, int b){        return a + b;    }   
5. 配置項目屬性。因為這是一個靜態鏈接庫,所以應在項目屬性的“配置屬性”下選擇“常規”,在其下的配置類型中選擇“靜態庫(.lib)。 6.編譯生成新的解決方案,在Debug文件夾下會得到mylib.lib (對象文件庫),將該.lib文件和相應頭文件給用戶,用戶就可以使用該庫里的函數了。

1.2.2 靜態庫的使用

方法一:配置項目屬性
   A、添加工程的頭文件目錄:工程---屬性---配置屬性---c/c++---常規---附加包含目錄:加上頭文件存放目錄。    B、添加文件引用的lib靜態庫路徑:工程---屬性---配置屬性---鏈接器---常規---附加庫目錄:加上lib文件存放目錄。    C  然後添加工程引用的lib文件名:工程---屬性---配置屬性---鏈接器---輸入---附加依賴項:加上lib文件名。   
方法二:使用編譯語句
   #pragma comment(lib,"./mylib.lib")   
方法三:添加工程中
   就像你添加.h和.cpp文件一樣,把lib文件添加到工程文件列表中去.    切換到"解決方案視圖",--->選中要添加lib的工程-->點擊右鍵-->"添加"-->"現有項"-->選擇lib文件-->確定.   
 

1.2.3 靜態庫優缺點

 
   n  靜態庫對函數庫的鏈接是放在編譯時期完成的,靜態庫在程式的鏈接階段被覆制到了程式中,和程式運行的時候沒有關係;    n  程式在運行時與函數庫再無瓜葛,移植方便。    n  浪費空間和資源,所有相關的目標文件與牽涉到的函數庫被鏈接合成一個可執行文件。   
    記憶體和磁碟空間 靜態鏈接這種方法很簡單,原理上也很容易理解,在操作系統和硬體不發達的早期,絕大部門系統採用這種方案。隨著電腦軟體的發展,這種方法的缺點很快暴露出來,那就是靜態鏈接的方式對於電腦記憶體和磁碟空間浪費非常嚴重。特別是多進程操作系統下,靜態鏈接極大的浪費了記憶體空間。在現在的linux系統中,一個普通程式會用到c語言靜態庫至少在1MB以上,那麼如果磁碟中有2000個這樣的程式,就要浪費將近2GB的磁碟空間。 程式開發和發佈 空間浪費是靜態鏈接的一個問題,另一個問題是靜態鏈接對程式的更新、部署和發佈也會帶來很多麻煩。比如程式中所使用的mylib.lib是由一個第三方廠商提供的,當該廠商更新容量mylib.lib的時候,那麼我們的程式就要拿到最新版的mylib.lib,然後將其重新編譯鏈接後,將新的程式整個發佈給用戶。這樣的做缺點很明顯,即一旦程式中有任何模塊更新,整個程式就要重新編譯鏈接、發佈給用戶,用戶要重新安裝整個程式。  

1.3 vs下動態庫創建和使用

要解決空間浪費和更新困難這兩個問題,最簡單的辦法就是把程式的模塊相互分割開來,形成獨立的文件,而不是將他們靜態的鏈接在一起。簡單地講,就是不對哪些組成程式的目標程式進行鏈接,等程式運行的時候才進行鏈接。也就是說,把整個鏈接過程推遲到了運行時再進行,這就是動態鏈接的基本思想。

1.3.1 動態庫的創建

1. 創建一個新項目,在已安裝的模板中選擇“常規”,在右邊的類型下選擇“空項目”,在名稱和解決方案名稱中輸入mydll。點擊確定。 2.在解決方案資源管理器的頭文件中添加,mydll.h文件,在源文件添加mydll.c文件(即實現文件)。 3.在test.h文件中添加如下代碼:
   #ifndef TEST_H    #define TEST_H         __declspec(dllexport) int myminus(int a, int b);         #endif   
5.在test.c文件中添加如下代碼:
   #include"test.h"    __declspec(dllexport) int myminus(int a, int b){        return a - b;    }   
5. 配置項目屬性。因為這是一個動態鏈接庫,所以應在項目屬性的“配置屬性”下選擇“常規”,在其下的配置類型中選擇“動態庫(.dll)。 6.編譯生成新的解決方案,在Debug文件夾下會得到mydll.dll (對象文件庫),將該.dll文件、.lib文件和相應頭文件給用戶,用戶就可以使用該庫里的函數了。
   疑問一:__declspec(dllexport)是什麼意思?    動態鏈接庫中定義有兩種函數:導出函數(export  function)和內部函數(internal  function)。 導出函數可以被其它模塊調用,內部函數在定義它們的DLL程式內部使用。         疑問二:動態庫的lib文件和靜態庫的lib文件的區別?    在使用動態庫的時候,往往提供兩個文件:一個引入庫(.lib)文件(也稱“導入庫文件”)和一個DLL(.dll)文件。雖然引入庫的尾碼名也是“lib”,但是,動態庫的引入庫文件和靜態庫文件有著本質的區別,對一個DLL文件來說,其引入庫文件(.lib)包含該DLL導出的函數和變數的符號名,而.dll文件包含該DLL實際的函數和數據。在使用動態庫的情況下,在編譯鏈接可執行文件時,只需要鏈接該DLL的引入庫文件,該DLL中的函數代碼和數據並不複製到可執行文件,直到可執行程式運行時,才去載入所需的DLL,將該DLL映射到進程的地址空間中,然後訪問DLL中導出的函數。   
 

1.3.2 動態庫的使用

方法一:隱式調用
        創建主程式TestDll,將mydll.h、mydll.dll和mydll.lib複製到源代碼目錄下。    (P.S:頭文件Func.h並不是必需的,只是C++中使用外部函數時,需要先進行聲明)    在程式中指定鏈接引用鏈接庫 : #pragma comment(lib,"./mydll.lib")   
  方法二:顯式調用
       HANDLE  hDll; //聲明一個dll實例文件句柄        hDll  = LoadLibrary("mydll.dll"); //導入動態鏈接庫        MYFUNC  minus_test; //創建函數指針        //獲取導入函數的函數指針        minus_test = (MYFUNC)GetProcAddress(hDll, "myminus");   

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本章旨在講解外掛實現原理,未深入涉及至代碼層面。希望能與對這方面感興趣的朋友多多交流,畢竟理論是死的,套路是固定的,只有破解經驗是花大量時間和心血積累的。 對於單機游戲而言,游戲中絕大部分的參數(比如血、藍、能量亦或是金幣)都存儲在電腦的堆棧中,一些類似劇情進度的則加密後寫入本地的自定義配置文件中 ...
  • 之前公司下達了開發微信只一塊的任務,然後我就去網上取了一番經,可是感覺對於我這種微信開發的新手來說,所需要的東西太多,太凌亂了,然後整個人就懵逼了。 費了很長時間才將微信介面調用完成。所以吶,我整理了一下,調用微信介面前需要準備的內容。 1.微信公眾平臺的appid 2.微信公眾平臺的secret ...
  • 反射是.NET中的重要機制,通過反射,可以在運行時獲得程式或程式集中每一個類型(包括類、結構、委托、介面和枚舉等)的成員和成員的信息。有了反射,即可對每一個類型瞭如指掌。另外我還可以直接創建對象,即使這個對象的類型在編譯時還不知道。 Anker_張(博客園)http://www.cnblogs.co ...
  • 剛做了一個小改動,需要在微信端顯示另外一個網站中通過富文本編輯後的信息,當然其中包括一些圖片內容。 其他的顯示都沒有問題,唯獨照片無法正常顯示,一直都是破碎的圖片樣式。 經過調試發現,圖片的顯示地址一直為另外一個網站的hosturl+path,然後發現資料庫中富文本的內容只有path,也沒有註明ho ...
  • 期望: 1.球體接觸到框體後反彈 2.設置速度按鍵,按下後改變球體速度、顏色狀態 具體實現: ...
  • 大家都知道main方法的參數就是一個數組類型的,那麼它其實也是可以改成不定參數類型。我試了試,並調用了一些彈出來的方法。 嗯,我把Sting後面的“[ ]”換成了三個點(...),這三個點代表Java中的可變數組參數。可變的參數類型(variable argument type),也稱為不定參數類型 ...
  • 項目中需要對Excel進行操作,把數據中的數據寫入到Excel文件中。在數據量大的情況下,操作Excel是一件費時的操作。 但是執行到下列代碼時就會出現空指針的情況: 第四行返回的workbooks指針是一個空指針,無法進行向下的Excel操作。這是因為QAxObject對象是預設在單線程下使用, ...
  • 索引 簡述 準備 示例 效果圖 結語 簡述 我在使用opencv2或3的時候想要在圖片上添加中文文字,需要去下載Freetype庫,編譯好鏈接到opencv庫中才能中文的輸出。網上大部分在圖片中插入中文的教程還是win+vs的配置教程。像我這種win下有環境,linux下有環境的人來說,想要同步代碼 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...