轉(zhuǎn)載:http://www.cnblogs.com/TenosDoIt/p/3203137.html
首先介紹一下靜態(tài)庫(靜態(tài)鏈接庫)乳讥、動(dòng)態(tài)庫(動(dòng)態(tài)鏈接庫)的概念聪舒,首先兩者都是代碼共享的方式昆雀。
靜態(tài)庫:在鏈接步驟中辱志,連接器將從庫文件取得所需的代碼蝠筑,復(fù)制到生成的可執(zhí)行文件中,這種庫稱為靜態(tài)庫揩懒,其特點(diǎn)是可執(zhí)行文件中包含了庫代碼的一份完整拷貝什乙;缺點(diǎn)就是被多次使用就會(huì)有多份冗余拷貝。即靜態(tài)庫中的指令都全部被直接包含在最終生成的 EXE 文件中了旭从。在vs中新建生成靜態(tài)庫的工程稳强,編譯生成成功后,只產(chǎn)生一個(gè).lib文件
動(dòng)態(tài)庫:動(dòng)態(tài)鏈接庫是一個(gè)包含可由多個(gè)程序同時(shí)使用的代碼和數(shù)據(jù)的庫和悦,DLL不是可執(zhí)行文件退疫。動(dòng)態(tài)鏈接提供了一種方法,使進(jìn)程可以調(diào)用不屬于其可執(zhí)行代碼的函數(shù)鸽素。函數(shù)的可執(zhí)行代碼位于一個(gè) DLL 中褒繁,該 DLL 包含一個(gè)或多個(gè)已被編譯、鏈接并與使用它們的進(jìn)程分開存儲(chǔ)的函數(shù)馍忽。在vs中新建生成動(dòng)態(tài)庫的工程棒坏,編譯成功后,產(chǎn)生一個(gè).lib文件和一個(gè).dll文件
那么上述靜態(tài)庫和動(dòng)態(tài)庫中的lib有什么區(qū)別呢遭笋?
靜態(tài)庫中的lib:該LIB包含函數(shù)代碼本身(即包括函數(shù)的索引坝冕,也包括實(shí)現(xiàn)),在編譯時(shí)直接將代碼加入程序當(dāng)中
動(dòng)態(tài)庫中的lib:該LIB包含了函數(shù)所在的DLL文件和文件中函數(shù)位置的信息(索引)瓦呼,函數(shù)實(shí)現(xiàn)代碼由運(yùn)行時(shí)加載在進(jìn)程空間中的DLL提供
總之喂窟,lib是編譯時(shí)用到的,dll是運(yùn)行時(shí)用到的央串。如果要完成源代碼的編譯磨澡,只需要lib;如果要使動(dòng)態(tài)鏈接的程序運(yùn)行起來质和,只需要dll稳摄。
以下例子均在vs2010上測試
生成動(dòng)態(tài)庫
新建項(xiàng)目--win32項(xiàng)目--填寫項(xiàng)目名--確定--下一步--應(yīng)用程序類型:選擇dll--附加選項(xiàng):選擇導(dǎo)出符號(hào)--完成
可以看到生成了一個(gè)dllmain.cpp 文件,這是dll應(yīng)用程序的入口饲宿,注意它和普通工程的入口main函數(shù)不同厦酬,這個(gè)文件我們不需要修改。
在這個(gè)動(dòng)態(tài)庫中我們舉例導(dǎo)出一個(gè)變量瘫想,一個(gè)類弃锐,一個(gè)函數(shù),頭文件dll.h如下:
1//新建生成dll的工程時(shí)殿托,vs默認(rèn)定義了宏DLL_EXPORT,因此霹菊,DLL_API 是 __declspec(dllexport),用來導(dǎo)出2//當(dāng)我們?cè)陟o態(tài)調(diào)用dll時(shí),我們包含該頭文件旋廷,由于沒有定義DLL_EXPORT谆棺,所以DLL_API是3//__declspec(dllimport),用來導(dǎo)入4#ifdef DLL_EXPORTS5#defineDLL_API __declspec(dllexport)6#else7#defineDLL_API __declspec(dllimport)8#endif910//導(dǎo)出類11classDLL_API Cdll {12public:13Cdll(void);14//TODO: 在此添加您的方法舍哄。15};1617//導(dǎo)出變量葫掉,變量在.cpp文件中定義18externDLL_APIintndll;1920//導(dǎo)出函數(shù)拓哺,加extern "C",是為了保證編譯時(shí)生成的函數(shù)名不變,這樣動(dòng)態(tài)調(diào)用dll時(shí)才能21//正確獲取函數(shù)的地址22extern"C"DLL_APIintfndll(void);
dll.cpp 文件如下:
1#include"dll.h"234//這是導(dǎo)出變量的一個(gè)示例5DLL_APIintndll=6;67//這是導(dǎo)出函數(shù)的一個(gè)示例扎运。8DLL_APIintfndll(void)9{10return42;11}1213//這是已導(dǎo)出類的構(gòu)造函數(shù)瑟曲。14//有關(guān)類定義的信息,請(qǐng)參閱 dll.h15Cdll::Cdll()16{17return;18}
有兩種方法調(diào)用動(dòng)態(tài)庫豪治,一種隱式鏈接洞拨,一種顯示鏈接。
調(diào)用動(dòng)態(tài)庫:隱式鏈接
隱式鏈接 需要.h文件负拟,dll文件烦衣,lib文件
(1)將dll放到工程的工作目錄
(2)設(shè)置項(xiàng)目屬性--vc++目錄--庫目錄為lib所在的路徑
(3)將lib添加到項(xiàng)目屬性--鏈接器--輸入--附加依賴項(xiàng)(或者直接在源代碼中加入#pragma comment(lib, “**.lib”))
(4)在源文件中添加.h頭文件
然后就像平常一樣調(diào)用普通函數(shù)、類掩浙、變量
調(diào)用動(dòng)態(tài)庫:顯示鏈接
顯示鏈接 只需要.dll文件花吟,但是這種調(diào)用方式不能調(diào)用dll中的變量或者類(其實(shí)可以調(diào)用類,但是相當(dāng)麻煩厨姚,有興趣者可參考http://blog.csdn.net/jdcb2001/article/details/1394883)
顯示調(diào)用主要使用WIN32 API函數(shù)LoadLibrary衅澈、GetProcAddress,舉例如下:
1typedefint(*dllfun)(void);//定義指向dll中函數(shù)的函數(shù)指針2HINSTANCE hlib = LoadLibrary(".\\dll.dll");3if(!hlib)4{5std::cout<<"load dll error\n";6return-1;7}8dllfun fun = (dllfun)GetProcAddress(hlib,"fndll");9if(!fun)10{11std::cout<<"load fun error\n";12return-1;13}14fun();
生成靜態(tài)庫
新建項(xiàng)目--win32項(xiàng)目--填寫項(xiàng)目名--確定--下一步--應(yīng)用程序類型:選擇靜態(tài)庫
靜態(tài)庫項(xiàng)目沒有main函數(shù)谬墙,也沒有像dll項(xiàng)目中的dllmain今布。
創(chuàng)建項(xiàng)目后添加.h文件,添加相應(yīng)的導(dǎo)出函數(shù)芭梯、變量或類险耀,如下所示
1#ifndef _MYLIB_H_2#define_MYLIB_H_34voidfun(inta);56externintk;78classtestclass9{10public:11testclass();12voidprint();13};1415#endif
.cpp文件如下
1#include"stdafx.h"2#include"lib.h"3#include 45voidfun(inta)6{7std::cout<
編譯工程后就會(huì)生成一個(gè).lib文件
需要.h文件弄喘,lib文件
(1)設(shè)置項(xiàng)目屬性--vc++目錄--庫目錄為lib所在的路徑
(2)將lib添加到項(xiàng)目屬性--鏈接器--輸入--附加依賴項(xiàng)(或者直接在源代碼中加入#pragma comment(lib, “**.lib”))
(3)在源文件中添加.h頭文件
然后就像平常一樣調(diào)用普通函數(shù)玖喘、類、變量蘑志,舉例如下:
1#include 2#include"lib.h"34#pragmacomment(lib, "lib.lib")56intmain()7{8fun(4);9std::cout<
【版權(quán)聲明】轉(zhuǎn)載請(qǐng)注明出處http://www.cnblogs.com/TenosDoIt/p/3203137.html