真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

C++中的動態(tài)庫和靜態(tài)庫(Windows)

庫:

創(chuàng)新互聯(lián)建站長期為上1000+客戶提供的網(wǎng)站建設(shè)服務,團隊從業(yè)經(jīng)驗10年,關(guān)注不同地域、不同群體,并針對不同對象提供差異化的產(chǎn)品和服務;打造開放共贏平臺,與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為博湖企業(yè)提供專業(yè)的網(wǎng)站建設(shè)、做網(wǎng)站,博湖網(wǎng)站改版等技術(shù)服務。擁有十載豐富建站經(jīng)驗和眾多成功案例,為您定制開發(fā)。

在C/C++中,使用庫(Library)的技術(shù),可以將編譯好的符號提供給第三方使用。

庫有兩種:

1、動態(tài)庫 Dynamic-Link Library (DLL)    (Linux下叫做 Shared Library)

2、靜態(tài)庫 Static Library

一、動態(tài)庫的創(chuàng)建和使用

創(chuàng)建DLL:

用VC創(chuàng)建一個類型為 “dll”的控制臺項目,VC會自動創(chuàng)建DLL的項目框架

它自動生成一個DllMain函數(shù),可以類比普通應用程序中的main函數(shù)

VC項目設(shè)置:

1、取消“預編譯頭文件”

2、改為 “/MTd編譯”

3、修改輸出的DLL的名字 (my.dll)

C++ 中的動態(tài)庫和靜態(tài)庫(Windows)

C++ 中的動態(tài)庫和靜態(tài)庫(Windows)

C++ 中的動態(tài)庫和靜態(tài)庫(Windows)

編譯,得到 *.lib 和 *.dll,其中:

*.dll:

包含所有代碼編譯成的指令

*.lib:包含一個列表,表名my.dll中含有哪些符號,每個符號對應在dll中的位置。(被導出的符號)

所以,*.lib比*.dll的文件體積小得多

如果想導出一個全局函數(shù),就用關(guān)鍵字 __declspec(dllexport)來聲明

注意:這是VC平臺特有的關(guān)鍵字,在linux平臺下不可用

使用如下:

template 
__declspec(dllexport) void MySwap(T& obj1, T& obj2)
{
	T tmp = obj1;
	obj1 = obj2;
	obj2 = tml;
}

使用dll:

#pragma  comment(lib, "12_18_DLL01")

__declspec(dllimport) int Add(int a, int b);

int main()
{
	int ret = Add(1, 2);
	std::cout << ret << std::endl;
	return 0;
}

但這個地方我發(fā)現(xiàn)了一個問題:

__declspec(dllimport) int Add(int a, int b);

這行代碼表示導入dll文件中的符號

但一開始我錯誤得寫成了 export, 結(jié)果居然仍然是正確的

沒有深究,初步推測是編譯器優(yōu)化了 (IDE: VS2015),甚至不寫前面的關(guān)鍵字,直接寫成函數(shù)的聲明,程序也是能正確執(zhí)行的

DLL的部署位置:

1、可執(zhí)行文件所在目錄

2、進程當前目錄

3、系統(tǒng)目錄 (C:\Windows\System32\    和  C:\Windows\System\)

4、Windows目錄 (C:\Windows\)

5、環(huán)境變量 PATH 中的目錄

通過初步接觸DLL的發(fā)布和使用,相比普通的聲明、定義,會發(fā)現(xiàn)DLL有以下作用:

1、隱藏了代碼

2、公開了功能

當然,DLL的作用遠不止如此

二、DLL的加載和卸載

DLL的加載:

DLL不能獨立運行,只有當 *.exe 被運行時, *.dll 才會被加載運行。

在exe文件中有一些標識信息,表示該 exe 依賴哪些 dll 文件,操作系統(tǒng)據(jù)此去尋找、加載相應的dll文件。

exe 被加載到內(nèi)存,形成一個進程 process,dll也被加載到內(nèi)存,進程可以直接調(diào)用DLL中的函數(shù)(Code)

數(shù)據(jù)段和代碼段:

在dll文件中,至少分為兩個段:

1、代碼段:

存儲指令(函數(shù)體)

2、數(shù)據(jù)段:

數(shù)據(jù)段,存放全局變量

當 *.dll 被加載時,代碼段只被加載一次,是公共的。

數(shù)據(jù)段被每個程序各自拷貝一份,是私有的

三、DLL中的動態(tài)內(nèi)存管理

在dll中申請的動態(tài)內(nèi)存,必須在dll中釋放,否則會導致內(nèi)存泄漏 (這是由Windows自己的特點決定的)

四、DLL中使用頭文件

按照慣例,由模塊的作者提供頭文件,頭文件中應該用類型、函數(shù)聲明。

所以,我們在創(chuàng)建DLL時,應該附帶一份頭文件,而不是讓使用者自己去寫函數(shù)聲明。

五、DLL中導出一個類

導出類的定義,其實就是導出其成員函數(shù)

類的聲明格式:

class __declspec(dllimport) MyClass
{};

六、靜態(tài)庫的概念及使用

靜態(tài)庫:

static library,僅一個 *.lib 文件

靜態(tài)庫中直接就含有代碼段和數(shù)據(jù)段,在鏈接過程中,是直接把里面的東西鏈接過來,形成完整的可執(zhí)行程序

exe運行的時候不依賴 .lib 文件

創(chuàng)建:

1、建立一個新工程,工程類型為:靜態(tài)庫

2、不需要其他設(shè)置,直接編譯鏈接生成,得到 *.lib文件

使用:

#pragma comment(lib, "MyLib.lib")

int MyAdd(int a, int b);    //通常發(fā)布會把把聲明放到頭文件中,一并發(fā)布

靜態(tài)庫的注意事項:

1、靜態(tài)庫的使用不太方便:

如果該靜態(tài)庫是VS2008編譯的,那么APP也得用VS2008編譯,版本必須一致

此外,運行時庫(/MT、/MTd、/MD、/MDd)也必須要一致

因此可以看出,靜態(tài)庫的使用,約束條件是比較多的

靜態(tài)庫和動態(tài)庫的對比:

靜態(tài)庫優(yōu)點:

使用靜態(tài)庫,最后得到的可執(zhí)行程序執(zhí)行時對這個庫不再依賴

動態(tài)庫優(yōu)點:

便于升級更新,只要保持接口不變,可以通過更新DLL來升級程序,而不需要重新編譯程序

目前通常都使用動態(tài)庫

但動態(tài)庫也存在更多的安全方面的隱患,畢竟如果有人惡意替換DLL(能做到這一步的人往往是軟件團隊的內(nèi)部人員),程序的執(zhí)行將會違背編程者的本意.......

七、DLL的手動加載

之前加載DLL的方式是自動加載。

自動加載和手動加載:

1、自動加載

在編譯時指定dll,則當exe程序啟動運行時,首先加載相關(guān)的dll

(DLL在程序執(zhí)行前被加載,在程序結(jié)束后被卸載)

2、手動加載

在編譯時不指定dll,在運行時調(diào)用LoadLibrary來加載dll 

(這樣做,可以自己決定什么時候加載、什么時候卸載DLL)

手動加載的方式:

#include 
#include 

使用 LoadLibrary 來加載dll,

使用 FreeLibrary 來卸載dll,

它提供了一種在運行時手動加載dll的技術(shù)手段,增加了編程的靈活性

(只要有*.dll就可以,也不需要 *.lib 和 *.h )

對DLL的要求:

1、要求待調(diào)用的函數(shù)按“C”方式編譯(符號名即函數(shù)名)

extern "C" __declspec(dllexprot) int MyAdd(int a, int b);

2、dll文件放在可被系統(tǒng)搜索到的路徑

代碼:

#include 
#include 
#include 

int main()
{
	wchar_t* Path = L"12_18_DLL01.dll";
	HINSTANCE  handle = LoadLibrary(Path);	// 字符集兼容問題
	if (handle)
	{
		// 定義要找的函數(shù)原型
		typedef int(*DLL_FUNCTION_ADD) (int, int);
		// 找到目標函數(shù)的地址	注意實現(xiàn)必須用 extern "C" 的方式編譯
		DLL_FUNCTION_ADD dll_func = (DLL_FUNCTION_ADD)GetProcAddress( handle, "Add");
		if (dll_func)
		{
			// 調(diào)用該函數(shù)
			int result = dll_func(1, 2);
			std::cout << result << std::endl;
		}
	}
	FreeLibrary(handle);
	return 0;
}

八、項目的靜態(tài)編譯

有一種場景,將以往VS生成的 *.exe 程序拷貝到其他 沒有VS運行環(huán)境的機器上,這時候程序往往是無法運行的,這是因為,VC編譯默認采用動態(tài)編譯的方式,因此 要么給這個機器也安裝一套運行環(huán)境,要么采用靜態(tài)編譯的方式生成可執(zhí)行文件(*.exe)

靜態(tài)編譯后的程序,將會包含一切程序運行時所依賴的環(huán)境

對VC來說:

靜態(tài)編譯:

/MT  /MTd

動態(tài)編譯:

/MD  /MDd

C++ 中的動態(tài)庫和靜態(tài)庫(Windows)

動態(tài)編譯和靜態(tài)編譯的比較:

1、動態(tài)編譯不方便發(fā)布,但生成的可執(zhí)行文件體積較小

2、靜態(tài)編譯方便發(fā)布,但生成的可執(zhí)行文件體積較大


文章題目:C++中的動態(tài)庫和靜態(tài)庫(Windows)
分享路徑:http://weahome.cn/article/picpdh.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部