激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - C/C++ - VisualStudio2019構建C/C++靜態庫和動態庫dll的問題 附源碼

VisualStudio2019構建C/C++靜態庫和動態庫dll的問題 附源碼

2021-10-28 14:31張凱1 C/C++

這篇文章主要介紹了VisualStudio2019構建C/C++靜態庫和動態庫(dll)(文末附源碼),本文通過實例圖文相結合給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下

1. 靜態庫和動態庫

 1.1. 靜態鏈接庫

舉個例子,假如你在編寫一個C++工程,根據業務邏輯,這個工程需要用到一些工具類,例如集合操作的工具類(暫且叫他collection_utils),于是你直接定義一個collection_utils.h頭文件和一個collection_utils.cpp文件,在頭文件中寫一些工具函數的定義,在cpp文件中寫函數的實現邏輯;如下所示:

//---------------collection_utils.h-----------------------------
#ifndef COLLECTION_UTILS
#define COLLECTION_UTILS
//合并兩個集合
Collection mergeCollection(const Collection& c1,const Collection& c2);
#endif
//---------------collection_utils.h-----------------------------

//---------------collection_utils.cpp-----------------------------
#include "collection_utils.h"
#include <vector>
// .....
Collection mergeCollection(const Collection& c1,const Collection& c2){
	//....實現邏輯
}
//---------------collection_utils.cpp----------------

然后你發現這個工具類具有通用性,在其他項目中也有類似的工具類的需求,想讓同事也用上你這個工具類,防止重復造輪子,然后你就把這兩個文件發給你的同事,此時聰明的你想起來這樣做有個不好的地方,因為項目編譯的時候,make工具會逐個編譯每個文件生成obj模塊,然后通過連接器,把各個模塊連接起來,然后打包生成一個exe可執行鏡像,這樣只要把這個工具類引入任何一個項目,它都要經歷編譯到obj的過程,但是對于工具類代碼來說,幾乎是寫好了以后就不怎么變化的東西了,這樣每個工程都編譯一遍,豈不是浪費了時間?而且隨著工具類庫的增加,這種方法的弊端就會越明顯。
那有沒有一種方法,可以讓這些工具類庫代碼只編譯一次,讓連接器在連接的時候,把已經編譯好的函數直接拷貝過來,縮短項目的構建時間呢? 答案是肯定的,它就是靜態鏈接庫。
有了靜態鏈接庫,其他工程只需要在工程中引入函數聲明的頭文件,在連接的時候,把靜態鏈接庫的庫文件提供出來就可以完成工程的構建。其實靜態庫很常見,例如我們用的C標準庫中的math.h,如果你包含math.hstdio.h等頭文件,這些頭文件聲明的函數實現不是每次構建工程都會把這里的代碼編譯一遍的,他們都是以預編譯的靜態鏈接庫的形式提供,在連接的時候,把我們調用的函數代碼指令,從這些庫中拷貝到最終的可執行文件中。

1.1. 動態鏈接庫

我們上面說到的靜態連接庫是把預編譯的模塊拷貝到自己的模塊中,然后打包構建exe鏡像,這當然節省了編譯器的時間,但是從某種程度上講,還是有些不足,因為:

  1. 在每一個構建出的每一個exe鏡像中,都會有同一個函數的代碼拷貝,造成額外的空間開銷;
  2. 當這些靜態庫升級時,所有的模塊都要重新編譯;

那有沒有一種依賴方式,可以讓程序在編譯時,僅僅記錄調用函數的名稱,函數的實現代碼放在專門的一個地方,這樣的庫在內存中只裝在一份;等到調用時,根據調用函數的名稱到庫中查找得到函數的入口地址呢?當然有的,那就是動態鏈接庫(dll),顧名思義,這種類型的庫是在程序運行時,需要哪個函數,就加載對應的dll到內存中,然后動態把函數調用的符號引用連接到實際的調用地址,當然這一步是由操作系統完成的啦,自己的程序不需要操心,這個比靜態庫要節省空間,但是會存在動態連接(把符號引用轉為直接引用)的過程,對于調用性能要求較高的函數,可能會損失性能。

一般在windows系統中,動態鏈接庫的文件擴展名是.dll,靜態鏈接庫的名稱是.lib,在linux系統中,動態庫的擴展名是.so,靜態庫的擴展名是.a

2. 使用VisualStudio構建演示

VisualStudio 2019版本:16.8.3(社區版)

2.1. 靜態庫構建演示

創建一個名稱為StaticDynamicLibraryStudy空白解決方案

VisualStudio2019構建C/C++靜態庫和動態庫dll的問題 附源碼
VisualStudio2019構建C/C++靜態庫和動態庫dll的問題 附源碼
VisualStudio2019構建C/C++靜態庫和動態庫dll的問題 附源碼

添加一個靜態庫項目

VisualStudio2019構建C/C++靜態庫和動態庫dll的問題 附源碼

項目類型選擇靜態庫

VisualStudio2019構建C/C++靜態庫和動態庫dll的問題 附源碼

填入名稱:StaticLibrary,

VisualStudio2019構建C/C++靜態庫和動態庫dll的問題 附源碼

最終新建好的項目目錄結構如下:

VisualStudio2019構建C/C++靜態庫和動態庫dll的問題 附源碼

我們可以把pch.cppStaticLibrary.cpp文件刪掉,添加自己的代碼,舉例如下:

VisualStudio2019構建C/C++靜態庫和動態庫dll的問題 附源碼

添加一個頭文件,例如sayHello.h,

VisualStudio2019構建C/C++靜態庫和動態庫dll的問題 附源碼

然后在源文件中新建一個源文件sayHello.cpp,實現sayHello邏輯,如下:

VisualStudio2019構建C/C++靜態庫和動態庫dll的問題 附源碼

然后,生成項目,在項目上右鍵,生成:

VisualStudio2019構建C/C++靜態庫和動態庫dll的問題 附源碼

然后報錯了,如下:

VisualStudio2019構建C/C++靜態庫和動態庫dll的問題 附源碼

如果遇到此報錯,只需要在項目上右鍵―>屬性,

VisualStudio2019構建C/C++靜態庫和動態庫dll的問題 附源碼

然后再次生成就可以了,

VisualStudio2019構建C/C++靜態庫和動態庫dll的問題 附源碼

當然這個目錄是可以改的,項目―>右鍵―>屬性―>配置屬性―>常規―>輸出目錄,大家可以去改。
然后在解決方案中增加一個測試控制臺項目,名稱叫做StaticLibraryTest,新建項目的過程上面有的,不再贅述。刪除掉多余的注釋,最終得到的項目結構:

VisualStudio2019構建C/C++靜態庫和動態庫dll的問題 附源碼

因為C++中函數遵守先聲明后使用的原則,為了能在新的項目中使用sayHello函數,首先需要聲明,因為演示只有這么一個函數,所以你可以在main函數之前,直接聲明,

VisualStudio2019構建C/C++靜態庫和動態庫dll的問題 附源碼

如果需要使用的函數比較多,也可以直接把頭文件復制到當前項目,然后include之,我覺得后一種比較規范,我就采用包含頭文件的方式了:

VisualStudio2019構建C/C++靜態庫和動態庫dll的問題 附源碼

目前我們只是解決了聲明函數的問題,但是函數的實現代碼我們還沒有包含進來,函數的實現代碼在上一步我們生成的StaticLibrary.lib中,如何包含呢?使用#pragma comment預處理指令,如下所示:

VisualStudio2019構建C/C++靜態庫和動態庫dll的問題 附源碼

生成項目,然后運行試試,

VisualStudio2019構建C/C++靜態庫和動態庫dll的問題 附源碼

如何設置當前解決方案運行那個項目的可執行文件呢?解決方案上―>右鍵―> 屬性―>通用屬性―>啟動項目―>單啟動項目,VS設置太多,自己慢慢摸索吧。

然后就會看到如下輸出:

VisualStudio2019構建C/C++靜態庫和動態庫dll的問題 附源碼

說明你成功了。nice~
其實,#pragma comment還可以指定相對路徑,是相對連接器構建時的工作目錄,在VS里,連接器的工作路徑就是項目根路徑,例如,改成如下形式,也是可以編譯運行的。

VisualStudio2019構建C/C++靜態庫和動態庫dll的問題 附源碼

當我們需要引入的靜態庫很多時,都使用絕對路徑或相對路徑寫難免麻煩,我們可以告訴連接器去哪個目錄下找庫文件,然后只需要在預處理指令中放入我們的靜態庫的名稱即可。VS中提供這種支持,配置方法:項目―>右鍵―>屬性―

>配置屬性―>鏈接器―>常規―>附加庫目錄

VisualStudio2019構建C/C++靜態庫和動態庫dll的問題 附源碼

然后把程序改成這樣,也可以運行的。當然你把lib文件復制到項目根目錄下,不用添加附加目錄,直接在預處理指令上寫庫名稱也是可以的。

VisualStudio2019構建C/C++靜態庫和動態庫dll的問題 附源碼

如果我們這一句也不想寫,可以直接在VS中指定包含哪個庫,操作方法,項目―>右鍵―>屬性―>配置屬性―>鏈接器―>輸入―>附加依賴項

VisualStudio2019構建C/C++靜態庫和動態庫dll的問題 附源碼

添加我們的庫名稱,這個時候直接寫庫的名稱,前提是已經配置了附加目錄,如果沒有配置附加目錄,這里需要寫全路徑或相對路徑,

VisualStudio2019構建C/C++靜態庫和動態庫dll的問題 附源碼

然后把程序改成這樣,

VisualStudio2019構建C/C++靜態庫和動態庫dll的問題 附源碼

也是可以運行成功的。

2.2. 動態庫構建演示

還是在當前的解決方案里,新建一個項目,項目類型選擇動態庫,名稱是DynamicLibrary

VisualStudio2019構建C/C++靜態庫和動態庫dll的問題 附源碼

新建以后是這樣的:

VisualStudio2019構建C/C++靜態庫和動態庫dll的問題 附源碼

這里的dllMain是dll的入口點,然后我們在添加sayHello.hsayhello.cpp,只不過頭文件需要加上__declspec

(dllexport),如下圖:

VisualStudio2019構建C/C++靜態庫和動態庫dll的問題 附源碼

這個標識的意思是,當前的sayHello函數需要從dll導出,相當于暴漏給外部的服務接口。在cpp文件中我們打?。?code>Hello,I am from dynamic library,然后項目―>右鍵―>生成,會生成3個文件:

VisualStudio2019構建C/C++靜態庫和動態庫dll的問題 附源碼

其中lib文件是動態庫的導入庫文件,這個文件是讓連接器在連接的時候,只需要記錄調用函數的名稱和在dll中的偏移地址,而不去拷貝其代碼實現,等到運行的時候,會由操作系統把動態庫的地址映射到當前進程的地址空間。
我們現在再添加一個控制臺項目DynamicLibraryTest,在里面進行sayHello函數的聲明,注意聲明時,要用如下方式:

VisualStudio2019構建C/C++靜態庫和動態庫dll的問題 附源碼

然后還需要像靜態庫一樣,使用#progma commen預處理指令,把lib導入庫文件引入進來,具體引入的方法我就不再贅述了,上面有說。最終就像這樣:

VisualStudio2019構建C/C++靜態庫和動態庫dll的問題 附源碼

然后,工程―>右鍵―>生成,然后運行,結果如下:(這里需要保證你的可執行文件和dll在同一目錄,當然把dll文件添加到path路徑也是可以的)

VisualStudio2019構建C/C++靜態庫和動態庫dll的問題 附源碼

這種方式叫做隱式鏈接,調用函數時,程序是如何找到dll中的入口地址的,完全是連接器幫我們做了,那我們能不能手動找到呢?即在程序運行時,動態的獲取到某個函數的句柄? 如果我們只有一個dll文件,沒有導入庫,但是我們知道里里面的函數聲明,這個時候我們該怎么調用呢?下面我們就看看顯式鏈接。
要顯式鏈接,首先需要修改一下原來的動態庫,VS中新建一個模塊定義文件,項目―>右鍵―>添加―>新建項―>Visual C++ ―>代碼―>模塊定義文件(def)

VisualStudio2019構建C/C++靜態庫和動態庫dll的問題 附源碼
名稱我就叫做DynamicLibrary.def,內容如下:

VisualStudio2019構建C/C++靜態庫和動態庫dll的問題 附源碼

然后,重新生成,在DynamicLibraryTest項目的main函數中,寫上如下代碼:

VisualStudio2019構建C/C++靜態庫和動態庫dll的問題 附源碼

然后,重新生成,運行,有點像Java的反射,結果圖我就不貼了。LoadLibrary中的路徑可以只使用dll的名稱,前提是dll必須在可執行文件同級目錄或在path路徑中。

3. 總結

以上就是靜態庫和動態庫的所有內容了,本文只是在Windows平臺進行演示,后續有空會增加在Linux平臺的演示,一步一步教會你,源碼已上傳Gitee碼云倉庫,編輯倉促,如有發現錯誤,請大家不吝賜教。

到此這篇關于VisualStudio2019構建C/C++靜態庫和動態庫dll的問題 附源碼的文章就介紹到這了,更多相關VisualStudio2019 dll動態庫內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://blog.csdn.net/qq_37684467/article/details/115058957

延伸 · 閱讀

精彩推薦
  • C/C++詳解c語言中的 strcpy和strncpy字符串函數使用

    詳解c語言中的 strcpy和strncpy字符串函數使用

    strcpy 和strcnpy函數是字符串復制函數。接下來通過本文給大家介紹c語言中的strcpy和strncpy字符串函數使用,感興趣的朋友跟隨小編要求看看吧...

    spring-go5642021-07-02
  • C/C++c++ 單線程實現同時監聽多個端口

    c++ 單線程實現同時監聽多個端口

    這篇文章主要介紹了c++ 單線程實現同時監聽多個端口的方法,幫助大家更好的理解和學習使用c++,感興趣的朋友可以了解下...

    源之緣11542021-10-27
  • C/C++學習C++編程的必備軟件

    學習C++編程的必備軟件

    本文給大家分享的是作者在學習使用C++進行編程的時候所用到的一些常用的軟件,這里推薦給大家...

    謝恩銘10102021-05-08
  • C/C++C++之重載 重定義與重寫用法詳解

    C++之重載 重定義與重寫用法詳解

    這篇文章主要介紹了C++之重載 重定義與重寫用法詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下...

    青山的青6062022-01-04
  • C/C++深入理解goto語句的替代實現方式分析

    深入理解goto語句的替代實現方式分析

    本篇文章是對goto語句的替代實現方式進行了詳細的分析介紹,需要的朋友參考下...

    C語言教程網7342020-12-03
  • C/C++C/C++經典實例之模擬計算器示例代碼

    C/C++經典實例之模擬計算器示例代碼

    最近在看到的一個需求,本以為比較簡單,但花了不少時間,所以下面這篇文章主要給大家介紹了關于C/C++經典實例之模擬計算器的相關資料,文中通過示...

    jia150610152021-06-07
  • C/C++C語言中炫酷的文件操作實例詳解

    C語言中炫酷的文件操作實例詳解

    內存中的數據都是暫時的,當程序結束時,它們都將丟失,為了永久性的保存大量的數據,C語言提供了對文件的操作,這篇文章主要給大家介紹了關于C語言中文件...

    針眼_6702022-01-24
  • C/C++C語言實現電腦關機程序

    C語言實現電腦關機程序

    這篇文章主要為大家詳細介紹了C語言實現電腦關機程序,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    xiaocaidayong8482021-08-20
主站蜘蛛池模板: 久久久成人精品视频 | 在线播放黄色片 | 91成人在线免费观看 | 日韩黄色影视 | 国产成人精品二区 | 亚洲精品无码不卡在线播放he | 免费毛片免费看 | 国产精品免费久久久久久 | av中文字幕免费在线观看 | 高清视频一区二区 | 嫩草影院在线观看网站成人 | 国产精品剧情一区二区三区 | 亚洲欧美日韩在线 | 黄片毛片一级 | 91免费影视 | 一级黄色片武则天 | 欧美视频国产 | 日韩黄网站 | 女女久久 | 免费黄色入口 | 日韩黄色精品 | 国产日韩在线视频 | 久久一区国产 | 国产青草网 | 欧日韩在线视频 | 欧美成年性h版影视中文字幕 | 成人毛片在线 | 日韩黄色片免费看 | 久久久久久久爱 | 色视频欧美 | fc2国产成人免费视频 | 久久久综合视频 | 国产69久久久 | 成人资源在线观看 | 国产午夜精品久久久久久久蜜臀 | 久久久久久久黄色片 | 91成人免费视频 | 羞羞漫画无遮挡观看 | av色先锋 | 欧美性a视频 | 91看片在线看 |