一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專(zhuān)注于服務(wù)器技術(shù)及軟件下載分享
分類(lèi)導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語(yǔ)言|JavaScript|易語(yǔ)言|vb.net|

服務(wù)器之家 - 編程語(yǔ)言 - C/C++ - VisualStudio2019構(gòu)建C/C++靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)dll的問(wèn)題 附源碼

VisualStudio2019構(gòu)建C/C++靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)dll的問(wèn)題 附源碼

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

這篇文章主要介紹了VisualStudio2019構(gòu)建C/C++靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)(dll)(文末附源碼),本文通過(guò)實(shí)例圖文相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

1. 靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)

 1.1. 靜態(tài)鏈接庫(kù)

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

//---------------collection_utils.h-----------------------------
#ifndef COLLECTION_UTILS
#define COLLECTION_UTILS
//合并兩個(gè)集合
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){
	//....實(shí)現(xiàn)邏輯
}
//---------------collection_utils.cpp----------------

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

1.1. 動(dòng)態(tài)鏈接庫(kù)

我們上面說(shuō)到的靜態(tài)連接庫(kù)是把預(yù)編譯的模塊拷貝到自己的模塊中,然后打包構(gòu)建exe鏡像,這當(dāng)然節(jié)省了編譯器的時(shí)間,但是從某種程度上講,還是有些不足,因?yàn)椋?/p>

  1. 在每一個(gè)構(gòu)建出的每一個(gè)exe鏡像中,都會(huì)有同一個(gè)函數(shù)的代碼拷貝,造成額外的空間開(kāi)銷(xiāo);
  2. 當(dāng)這些靜態(tài)庫(kù)升級(jí)時(shí),所有的模塊都要重新編譯;

那有沒(méi)有一種依賴(lài)方式,可以讓程序在編譯時(shí),僅僅記錄調(diào)用函數(shù)的名稱(chēng),函數(shù)的實(shí)現(xiàn)代碼放在專(zhuān)門(mén)的一個(gè)地方,這樣的庫(kù)在內(nèi)存中只裝在一份;等到調(diào)用時(shí),根據(jù)調(diào)用函數(shù)的名稱(chēng)到庫(kù)中查找得到函數(shù)的入口地址呢?當(dāng)然有的,那就是動(dòng)態(tài)鏈接庫(kù)(dll),顧名思義,這種類(lèi)型的庫(kù)是在程序運(yùn)行時(shí),需要哪個(gè)函數(shù),就加載對(duì)應(yīng)的dll到內(nèi)存中,然后動(dòng)態(tài)把函數(shù)調(diào)用的符號(hào)引用連接到實(shí)際的調(diào)用地址,當(dāng)然這一步是由操作系統(tǒng)完成的啦,自己的程序不需要操心,這個(gè)比靜態(tài)庫(kù)要節(jié)省空間,但是會(huì)存在動(dòng)態(tài)連接(把符號(hào)引用轉(zhuǎn)為直接引用)的過(guò)程,對(duì)于調(diào)用性能要求較高的函數(shù),可能會(huì)損失性能。

一般在windows系統(tǒng)中,動(dòng)態(tài)鏈接庫(kù)的文件擴(kuò)展名是.dll,靜態(tài)鏈接庫(kù)的名稱(chēng)是.lib,在linux系統(tǒng)中,動(dòng)態(tài)庫(kù)的擴(kuò)展名是.so,靜態(tài)庫(kù)的擴(kuò)展名是.a

2. 使用VisualStudio構(gòu)建演示

VisualStudio 2019版本:16.8.3(社區(qū)版)

2.1. 靜態(tài)庫(kù)構(gòu)建演示

創(chuàng)建一個(gè)名稱(chēng)為StaticDynamicLibraryStudy空白解決方案

VisualStudio2019構(gòu)建C/C++靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)dll的問(wèn)題 附源碼
VisualStudio2019構(gòu)建C/C++靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)dll的問(wèn)題 附源碼
VisualStudio2019構(gòu)建C/C++靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)dll的問(wèn)題 附源碼

添加一個(gè)靜態(tài)庫(kù)項(xiàng)目

VisualStudio2019構(gòu)建C/C++靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)dll的問(wèn)題 附源碼

項(xiàng)目類(lèi)型選擇靜態(tài)庫(kù)

VisualStudio2019構(gòu)建C/C++靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)dll的問(wèn)題 附源碼

填入名稱(chēng):StaticLibrary,

VisualStudio2019構(gòu)建C/C++靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)dll的問(wèn)題 附源碼

最終新建好的項(xiàng)目目錄結(jié)構(gòu)如下:

VisualStudio2019構(gòu)建C/C++靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)dll的問(wèn)題 附源碼

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

VisualStudio2019構(gòu)建C/C++靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)dll的問(wèn)題 附源碼

添加一個(gè)頭文件,例如sayHello.h

VisualStudio2019構(gòu)建C/C++靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)dll的問(wèn)題 附源碼

然后在源文件中新建一個(gè)源文件sayHello.cpp,實(shí)現(xiàn)sayHello邏輯,如下:

VisualStudio2019構(gòu)建C/C++靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)dll的問(wèn)題 附源碼

然后,生成項(xiàng)目,在項(xiàng)目上右鍵,生成:

VisualStudio2019構(gòu)建C/C++靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)dll的問(wèn)題 附源碼

然后報(bào)錯(cuò)了,如下:

VisualStudio2019構(gòu)建C/C++靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)dll的問(wèn)題 附源碼

如果遇到此報(bào)錯(cuò),只需要在項(xiàng)目上右鍵―>屬性,

VisualStudio2019構(gòu)建C/C++靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)dll的問(wèn)題 附源碼

然后再次生成就可以了,

VisualStudio2019構(gòu)建C/C++靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)dll的問(wèn)題 附源碼

當(dāng)然這個(gè)目錄是可以改的,項(xiàng)目―>右鍵―>屬性―>配置屬性―>常規(guī)―>輸出目錄,大家可以去改。
然后在解決方案中增加一個(gè)測(cè)試控制臺(tái)項(xiàng)目,名稱(chēng)叫做StaticLibraryTest,新建項(xiàng)目的過(guò)程上面有的,不再贅述。刪除掉多余的注釋?zhuān)罱K得到的項(xiàng)目結(jié)構(gòu):

VisualStudio2019構(gòu)建C/C++靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)dll的問(wèn)題 附源碼

因?yàn)镃++中函數(shù)遵守先聲明后使用的原則,為了能在新的項(xiàng)目中使用sayHello函數(shù),首先需要聲明,因?yàn)檠菔局挥羞@么一個(gè)函數(shù),所以你可以在main函數(shù)之前,直接聲明,

VisualStudio2019構(gòu)建C/C++靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)dll的問(wèn)題 附源碼

如果需要使用的函數(shù)比較多,也可以直接把頭文件復(fù)制到當(dāng)前項(xiàng)目,然后include之,我覺(jué)得后一種比較規(guī)范,我就采用包含頭文件的方式了:

VisualStudio2019構(gòu)建C/C++靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)dll的問(wèn)題 附源碼

目前我們只是解決了聲明函數(shù)的問(wèn)題,但是函數(shù)的實(shí)現(xiàn)代碼我們還沒(méi)有包含進(jìn)來(lái),函數(shù)的實(shí)現(xiàn)代碼在上一步我們生成的StaticLibrary.lib中,如何包含呢?使用#pragma comment預(yù)處理指令,如下所示:

VisualStudio2019構(gòu)建C/C++靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)dll的問(wèn)題 附源碼

生成項(xiàng)目,然后運(yùn)行試試,

VisualStudio2019構(gòu)建C/C++靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)dll的問(wèn)題 附源碼

如何設(shè)置當(dāng)前解決方案運(yùn)行那個(gè)項(xiàng)目的可執(zhí)行文件呢?解決方案上―>右鍵―> 屬性―>通用屬性―>啟動(dòng)項(xiàng)目―>單啟動(dòng)項(xiàng)目,VS設(shè)置太多,自己慢慢摸索吧。

然后就會(huì)看到如下輸出:

VisualStudio2019構(gòu)建C/C++靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)dll的問(wèn)題 附源碼

說(shuō)明你成功了。nice~
其實(shí),#pragma comment還可以指定相對(duì)路徑,是相對(duì)連接器構(gòu)建時(shí)的工作目錄,在VS里,連接器的工作路徑就是項(xiàng)目根路徑,例如,改成如下形式,也是可以編譯運(yùn)行的。

VisualStudio2019構(gòu)建C/C++靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)dll的問(wèn)題 附源碼

當(dāng)我們需要引入的靜態(tài)庫(kù)很多時(shí),都使用絕對(duì)路徑或相對(duì)路徑寫(xiě)難免麻煩,我們可以告訴連接器去哪個(gè)目錄下找?guī)煳募缓笾恍枰陬A(yù)處理指令中放入我們的靜態(tài)庫(kù)的名稱(chēng)即可。VS中提供這種支持,配置方法:項(xiàng)目―>右鍵―>屬性―

>配置屬性―>鏈接器―>常規(guī)―>附加庫(kù)目錄

VisualStudio2019構(gòu)建C/C++靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)dll的問(wèn)題 附源碼

然后把程序改成這樣,也可以運(yùn)行的。當(dāng)然你把lib文件復(fù)制到項(xiàng)目根目錄下,不用添加附加目錄,直接在預(yù)處理指令上寫(xiě)庫(kù)名稱(chēng)也是可以的。

VisualStudio2019構(gòu)建C/C++靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)dll的問(wèn)題 附源碼

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

VisualStudio2019構(gòu)建C/C++靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)dll的問(wèn)題 附源碼

添加我們的庫(kù)名稱(chēng),這個(gè)時(shí)候直接寫(xiě)庫(kù)的名稱(chēng),前提是已經(jīng)配置了附加目錄,如果沒(méi)有配置附加目錄,這里需要寫(xiě)全路徑或相對(duì)路徑

VisualStudio2019構(gòu)建C/C++靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)dll的問(wèn)題 附源碼

然后把程序改成這樣,

VisualStudio2019構(gòu)建C/C++靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)dll的問(wèn)題 附源碼

也是可以運(yùn)行成功的。

2.2. 動(dòng)態(tài)庫(kù)構(gòu)建演示

還是在當(dāng)前的解決方案里,新建一個(gè)項(xiàng)目,項(xiàng)目類(lèi)型選擇動(dòng)態(tài)庫(kù),名稱(chēng)是DynamicLibrary

VisualStudio2019構(gòu)建C/C++靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)dll的問(wèn)題 附源碼

新建以后是這樣的:

VisualStudio2019構(gòu)建C/C++靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)dll的問(wèn)題 附源碼

這里的dllMain是dll的入口點(diǎn),然后我們?cè)谔砑?code>sayHello.h和sayhello.cpp,只不過(guò)頭文件需要加上__declspec

(dllexport),如下圖:

VisualStudio2019構(gòu)建C/C++靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)dll的問(wèn)題 附源碼

這個(gè)標(biāo)識(shí)的意思是,當(dāng)前的sayHello函數(shù)需要從dll導(dǎo)出,相當(dāng)于暴漏給外部的服務(wù)接口。在cpp文件中我們打印:Hello,I am from dynamic library,然后項(xiàng)目―>右鍵―>生成,會(huì)生成3個(gè)文件:

VisualStudio2019構(gòu)建C/C++靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)dll的問(wèn)題 附源碼

其中l(wèi)ib文件是動(dòng)態(tài)庫(kù)的導(dǎo)入庫(kù)文件,這個(gè)文件是讓連接器在連接的時(shí)候,只需要記錄調(diào)用函數(shù)的名稱(chēng)和在dll中的偏移地址,而不去拷貝其代碼實(shí)現(xiàn),等到運(yùn)行的時(shí)候,會(huì)由操作系統(tǒng)把動(dòng)態(tài)庫(kù)的地址映射到當(dāng)前進(jìn)程的地址空間。
我們現(xiàn)在再添加一個(gè)控制臺(tái)項(xiàng)目DynamicLibraryTest,在里面進(jìn)行sayHello函數(shù)的聲明,注意聲明時(shí),要用如下方式:

VisualStudio2019構(gòu)建C/C++靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)dll的問(wèn)題 附源碼

然后還需要像靜態(tài)庫(kù)一樣,使用#progma commen預(yù)處理指令,把lib導(dǎo)入庫(kù)文件引入進(jìn)來(lái),具體引入的方法我就不再贅述了,上面有說(shuō)。最終就像這樣:

VisualStudio2019構(gòu)建C/C++靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)dll的問(wèn)題 附源碼

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

VisualStudio2019構(gòu)建C/C++靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)dll的問(wèn)題 附源碼

這種方式叫做隱式鏈接,調(diào)用函數(shù)時(shí),程序是如何找到dll中的入口地址的,完全是連接器幫我們做了,那我們能不能手動(dòng)找到呢?即在程序運(yùn)行時(shí),動(dòng)態(tài)的獲取到某個(gè)函數(shù)的句柄? 如果我們只有一個(gè)dll文件,沒(méi)有導(dǎo)入庫(kù),但是我們知道里里面的函數(shù)聲明,這個(gè)時(shí)候我們?cè)撛趺凑{(diào)用呢?下面我們就看看顯式鏈接
要顯式鏈接,首先需要修改一下原來(lái)的動(dòng)態(tài)庫(kù),VS中新建一個(gè)模塊定義文件,項(xiàng)目―>右鍵―>添加―>新建項(xiàng)―>Visual C++ ―>代碼―>模塊定義文件(def)

VisualStudio2019構(gòu)建C/C++靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)dll的問(wèn)題 附源碼
名稱(chēng)我就叫做DynamicLibrary.def,內(nèi)容如下:

VisualStudio2019構(gòu)建C/C++靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)dll的問(wèn)題 附源碼

然后,重新生成,在DynamicLibraryTest項(xiàng)目的main函數(shù)中,寫(xiě)上如下代碼:

VisualStudio2019構(gòu)建C/C++靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)dll的問(wèn)題 附源碼

然后,重新生成,運(yùn)行,有點(diǎn)像Java的反射,結(jié)果圖我就不貼了。LoadLibrary中的路徑可以只使用dll的名稱(chēng),前提是dll必須在可執(zhí)行文件同級(jí)目錄或在path路徑中。

3. 總結(jié)

以上就是靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)的所有內(nèi)容了,本文只是在Windows平臺(tái)進(jìn)行演示,后續(xù)有空會(huì)增加在Linux平臺(tái)的演示,一步一步教會(huì)你,源碼已上傳Gitee碼云倉(cāng)庫(kù),編輯倉(cāng)促,如有發(fā)現(xiàn)錯(cuò)誤,請(qǐng)大家不吝賜教。

到此這篇關(guān)于VisualStudio2019構(gòu)建C/C++靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)dll的問(wèn)題 附源碼的文章就介紹到這了,更多相關(guān)VisualStudio2019 dll動(dòng)態(tài)庫(kù)內(nèi)容請(qǐng)搜索服務(wù)器之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持服務(wù)器之家!

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

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 亚洲精品在线免费 | 国产成人综合网亚洲欧美在线 | 人皮高跟鞋在线观看 | 紧身短裙女教师波多野 | 日韩久久影院 | 91久久偷偷做嫩草影院免费 | 日韩欧美不卡片 | 动漫jk美女被爆羞羞漫画 | 精品无码一区二区三区中文字幕 | 色男人网 | 沉沦艳妇杨幂肉体小说 | 国产精品久久久久久影院 | 91久久精品青青草原伊人 | 亚洲一区二区三区91 | 小小水蜜桃3视频在线观看 小鸟酱喷水 | 欧美一区不卡二区不卡三区 | 天堂资源wwww在线看 | 国产在线播放91 | 日韩中文字幕在线不卡 | 白丝h视频| 国产成人精选免费视频 | 男人午夜视频在线观看 | 免费在线视频网站 | 污污的动态图合集 | 91视频国产精品 | 高跟丝袜麻麻求我调教 | 成人毛片高清视频观看 | 日不卡 | 免费港剧在线观看港剧 | 桃乃木香在线 | 大又大又黄又爽免费毛片 | 66j8影院xxxx深夜 | 亚洲精品国产成人7777 | 3d动漫被吸乳羞羞 | 日本手机在线视频 | 亚洲AV 无码AV 中文字幕 | 国产精品久久久久久久久 | 亚洲成人福利 | 国产婷婷高清在线观看免费 | 免费观看欧美性一级 | a毛片免费全部在线播放毛 a级在线看 |