***************************************************
更多精彩,歡迎進入:http://shop115376623.taobao.com
***************************************************
本文將創建一個簡單的動態鏈接庫,并編寫一個應用臺控制程序使用該動態鏈接庫,并提出了與實現相關的幾個問題,供初學者交流。
本文包含以下內容:
1、創建動態鏈接庫項目
2、向動態鏈接庫添加類
3、創建引用動態鏈接庫的應用程序
4、在控制臺應用程序中使用類庫的功能
5、更豐富的simpledll類和相關問題
參考資料
一、創建動態鏈接庫項目:
1、打開Microsoft?Visual?Studio?2010,選擇File->New->Project。
2、在New?Project中選擇Installed?Templates->Visual?C++->Win32。
3、選擇Win32?Console?Application,設置名稱:simpledll,設置解決方案名:zdddll。
4、單擊OK,在出現的Win32?Application?Wizard的Overview對話框中點擊Next。
5、在Application?Settings中,選擇Application?type下的DLL。
6、勾選Additional?options下的Empty?project。
7、單擊Finish創建項目。
二、向動態鏈接庫添加類:
1、添加新類頭文件。右鍵單擊simpledll項目,Add->New?Item,選擇Header?File(.h),設置名稱為simpledll,單擊Add。
2、添加新類源文件。右鍵單擊simpledll項目,Add->New?Item,選擇C++?File(.cpp),設置名稱為simpledll,單擊Add。
3、為新類添加內容。內容如下:
頭文件simpledll.h:
- //------------------?simpledll.h?----------------??
- ??
- #pragma?once;??
- ??
- //該宏完成在dll項目內部使用__declspec(dllexport)導出??
- //在dll項目外部使用時,用__declspec(dllimport)導入??
- //宏DLL_IMPLEMENT在simpledll.cpp中定義??
- #ifdef?DLL_IMPLEMENT??
- #define?DLL_API?__declspec(dllexport)??
- #else??
- #define?DLL_API?__declspec(dllimport)??
- #endif??
- ??
- namespace?zdd??
- {??
- ????//導出類??
- ????class?DLL_API?SimpleDll??
- ????{??
- ????public:??
- ????????SimpleDll();??
- ????????~SimpleDll();??
- ??
- ????????int?add(int?x,?int?y);?//簡單方法??
- ????};??
- }??
源文件simpledll.cpp:
- //------------------?simpledll.cpp?----------------??
- ??
- //注意此處的宏定義需要寫在#include?"simpledll.h"之前??
- //以完成在dll項目內部使用__declspec(dllexport)導出??
- //在dll項目外部使用時,用__declspec(dllimport)導入??
- #define?DLL_IMPLEMENT???
- ??
- #include?"simpledll.h"??
- ??
- namespace?zdd??
- {??
- ????SimpleDll::SimpleDll()??
- ????{??
- ??
- ????}??
- ??
- ????SimpleDll::~SimpleDll()??
- ????{??
- ??
- ????}??
- ??
- ????int?SimpleDll::add(int?x,?int?y)??
- ????{??
- ????????return?x+y;??
- ????}??
- }??
4、完成后點擊Build->Build?Solution,生成解決方案。可在~zdddll\Debug下查看生成的simpledll.lib和simpledll.dll.文件。
三、創建引用動態鏈接庫的應用程序:
1、選擇File->New->Project。
2、在New?Project中選擇Installed?Templates->Visual?C++->Win32。
3、選擇Win32?Console?Application,設置名稱:usesimpledll。選擇Add?to?solution。
4、單擊OK,在出現的Win32?Application?Wizard的Overview對話框中點擊Next。
5、在Application?Settings中,選擇Application?type下的Console?application。
6、取消Additional?options下的Precompiled?header,勾選Empty?project。
7、單擊Finish創建項目。
四、在控制臺應用程序中使用類庫的功能:
1、為控制臺應用程序添加main.cpp。右鍵單擊usesimpledll項目,Add->New?Item,選擇C++?File(.cpp),設置名稱為main,單擊Add。
2、為main.cpp添加內容。如下所示:
- //------------------?main.cpp?-------------------??
- #include?"simpledll.h"??
- using?namespace?zdd;??
- ??
- #include?<iostream>??
- using?namespace?std;??
- ??
- int?main(char?argc,?char**argv)??
- {??
- ????//??
- ????cout?<<?"----------------------"?<<endl;??
- ????SimpleDll?sd;??
- ????cout?<<?"sd.add:?3+5="?<<?sd.add(3,?5)<<endl;??
- ????cout?<<?"sd.getConst():?"<<sd.getConst()<<endl;??
- ??
- ????SimpleDll?*psd?=?new?SimpleDll;??
- ????cout?<<?"psd->add:?5+5="?<<?psd->add(5,?5)<<endl;??
- ????cout?<<?"psd->getConst():?"<<endl;??
- ??
- ????cout?<<?"----------------------"?<<endl;??
- ????cout?<<?"please?press?Enter?exit."<<endl;??
- ????getchar();??
- ????return?0;??
- }??
3、引用simpledll項目。右鍵單擊usesimpledll項目,選擇Properties->Common?Properties->Framework?and?References。點擊Add?New?Reference,選擇simpledll項目,單擊OK。
4、設置頭文件路徑。選擇Properties->Configuration?Properties->VC++?Directories。在Include?Directories項添加$(SolutionDir)\simpledll\,選擇應用,確定。
5、設置usesimpledll項目為活動項目。右鍵單擊usesimpledll項目,選擇Set?up?StartUp?Project。
6、生成解決方案。Debug運行結果如下:
- 3+5=8??
- 5+5=10??
五、更豐富的simpledll類和相關問題:
simpledll.h文件:
- //------------------?simpledll.h?----------------??
- ??
- #pragma?once;??
- ??
- //該宏完成在dll項目內部使用__declspec(dllexport)導出??
- //在dll項目外部使用時,用__declspec(dllimport)導入??
- //宏DLL_IMPLEMENT在simpledll.cpp中定義??
- #ifdef?DLL_IMPLEMENT??
- #define?DLL_API?__declspec(dllexport)??
- #else??
- #define?DLL_API?__declspec(dllimport)??
- #endif??
- ??
- namespace?zdd??
- {??
- ????//導出類??
- ????class?DLL_API?SimpleDll??
- ????{??
- ????public:??
- ????????SimpleDll();??
- ????????~SimpleDll();??
- ??
- ????????int?add(int?x,?int?y);?//簡單方法??
- ??
- ????????static?int?sub(int?x,?int?y);//靜態方法??
- ??
- ????????int?getConst();?//??
- ??
- ????????int?getNum();??
- ??
- ????private:??
- ????????void?setNum(int?n);??
- ????????int?num;??
- ????};??
- ??
- ????//全局變量??
- ????int?DLL_API?number;???
- ????SimpleDll?DLL_API?sdd;??
- ??
- ????//對于指針,下面兩種用法沒區別???
- ????SimpleDll?DLL_API?*psdd;??
- ????SimpleDll?*psdd1;??
- ??
- ????//方法??
- ????int?DLL_API?Add(int?a,?int?b);??
- ??
- ????SimpleDll?*createClass()??
- ????{??
- ????????return?new?SimpleDll;??
- ????}??
- ??
- /*?
- ????//問題1:若這樣使用,則出現如下錯誤:?
- ????//?error?C2059:?syntax?error?:?'__declspec(dllexport)'?
- ????//?error?C2143:?syntax?error?:?missing?';'?before?'{'?
- ????//?error?:?'__declspec(dllimport)'?
- ????//?error?C2143:?syntax?error?:?missing?';'?before?'{'?
- ????//?error?C2447:?'{'?:?missing?function?header?(old-style?formal?list?)?
- ????//為什么??
- ????SimpleDll*?DLL_API?createClass1()?
- ????{?
- ????????return?new?SimpleDll;?
- ????}?
- */??
- ??
- /*?
- ????//問題2:若這樣使用,則出現如下錯誤:?
- ????//Error?1???error?C2491:?'zdd::createClass1'?:?definition?of?dllimport?function?not?allowed?usesimpledll?
- ????//為什么??
- ????SimpleDll?DLL_API?*?createClass2()?
- ????{?
- ????????return?new?SimpleDll;?
- ????}?
- */??
- ????//問題3:這樣使用(實現在.cpp中),編譯沒有問題。??
- ????//但在main中應用時回出現以下錯誤:??
- ????//?error?LNK2019:?unresolved?external?symbol?"class?zdd::SimpleDll?*?__cdecl?zdd::createClass3(void)"?(?createClass3@zdd@@YAPAVSimpleDll@1@XZ)?referenced?in?function?_main??
- ????//該如何解決???
- ????SimpleDll?*createClass3();?//先別這樣用??
- ??
- ????//全局方法加DLL_API和不加DLL_API時的區別??
- ????int?DLL_API?getConst1();??
- ????//int?getConst2();?//不要這樣使用??
- ??
- ????//也不要這樣用??
- ????//否則當程序發布之后,如果只想通過更新.dll??
- ????//來達到更新程序數據的目的,比如將此處的100更新成10.??
- ????//通過下面的方法你是做不到的??
- ????int?getConst2()??
- ????{??
- ????????return?100;??
- //??????return?10;??
- ????}??
- ??
- ????//也不要這樣用,否則將出現如下錯誤??
- ????//error?C2491:?'zdd::getConst3'?:?definition?of?dllimport?function?not?allowed??
- /*?
- ????int?DLL_API?getConst3()?
- ????{?
- ????????return?100;?
- ????}?
- */??
- ????//不要這樣用,同理??
- ????int?others(int?a)??
- ????{??
- ????????return?a+10;??
- ????}??
- }??
simpledll.cpp文件:
- //------------------?simpledll.cpp?----------------??
- ??
- //注意此處的宏定義需要寫在#include?"simpledll.h"之前??
- //以完成在dll項目內部使用__declspec(dllexport)導出??
- //在dll項目外部使用時,用__declspec(dllimport)導入??
- #define?DLL_IMPLEMENT???
- ??
- #include?"simpledll.h"??
- ??
- namespace?zdd??
- {??
- ????SimpleDll::SimpleDll()??
- ????{??
- ??
- ????}??
- ??
- ????SimpleDll::~SimpleDll()??
- ????{??
- ??
- ????}??
- ??
- ????int?SimpleDll::add(int?x,?int?y)??
- ????{??
- ????????return?x+y;??
- ????}??
- ??
- ????int?SimpleDll::sub(int?x,?int?y)??
- ????{??
- ????????return?x-y;??
- ????}??
- ??
- ????int?SimpleDll::getConst()??
- ????{??
- ????????return?10;?//??
- ????}??
- ??
- ????void?SimpleDll::setNum(int?n)??
- ????{??
- ????????num?=?n;??
- ????}??
- ??
- ????int?SimpleDll::getNum()??
- ????{??
- ????????return?num;??
- ????}??
- ??
- ????extern?int?number?=?5;??
- ??
- ????int?Add(int?a,?int?b)??
- ????{??
- ????????return?a+b;??
- ????}??
- ??
- ????SimpleDll?*createClass3()??
- ????{??
- ????????return?new?SimpleDll;??
- ????}??
- ??
- ????int?getConst1()??
- ????{??
- ????????return?100;??
- ????????//return?10;??
- ????}??
- /*?
- ????//error?
- ????extern?int?getConst2()?
- ????{?
- ????????return?100;?
- ????}?
- */??
- }??
main.cpp文件:
- //------------------?main.cpp?-------------------??
- #include?"simpledll.h"??
- using?namespace?zdd;??
- ??
- #include?<iostream>??
- using?namespace?std;??
- ??
- int?main(char?argc,?char**argv)??
- {??
- ????//??
- ????cout?<<?"----------------------"?<<endl;??
- ????SimpleDll?sd;??
- ????cout?<<?"sd.add:?3+5="?<<?sd.add(3,?5)<<endl;??
- ????cout?<<?"sd.getConst():?"<<sd.getConst()<<endl;??
- ??
- ????SimpleDll?*psd?=?new?SimpleDll;??
- ????cout?<<?"psd->add:?5+5="?<<?psd->add(5,?5)<<endl;??
- ????cout?<<?"psd->getConst():?"<<endl;??
- ??
- ????cout?<<?"----------------------"?<<endl;??
- ????cout?<<?"SimpleDll::sub:?2-1="?<<?SimpleDll::sub(2,1)<<endl;??
- ??
- ????cout?<<?"----------------------"?<<endl;??
- ????cout?<<?"zdd::number:?"<<number<<endl;??
- ????number?=?10;??
- ????cout?<<?"changed?zdd::number:?"<<number<<endl;??
- ??????
- ????cout?<<?"----------------------"?<<endl;??
- ????cout?<<?"sdd.add:?6+8="?<<?sdd.add(6,8)<<endl;??
- ????cout?<<?"psdd->add:?6+8="?<<psdd->add(6,8)<<endl;??
- ????cout?<<?"psdd1->add:?6+8="?<<psdd1->add(6,8)<<endl;??
- ??
- ????cout?<<endl;??
- ????cout?<<?"sdd.getConst():?"<<sd.getConst()<<endl;??
- ????cout?<<?"psdd.getConst():?"<<psdd->getConst()<<endl;??
- ????cout?<<?"psdd1.getConst():?"<<psdd1->getConst()<<endl;??
- ??
- ????cout?<<?"----------------------"?<<endl;??
- ????cout?<<?"zdd::Add:?7+8="<<Add(7,8)<<endl;??
- ??
- ????cout?<<?"----------------------"?<<endl;??
- ????SimpleDll?*p?=?createClass();??
- ????cout?<<?"create->add:?2+3="?<<p->add(3,2)<<endl;??
- ????cout?<<?"create->getConst():?"<<p->getConst()<<endl;??
- ????cout?<<?"----------------------"?<<endl;??
- ??
- //??SimpleDll?*p3?=?createClass3();??
- //??cout?<<?"create3->add:?2+3="?<<p3->add(3,2)<<endl;??
- //??cout?<<?"create3->getConst():?"<<p3->getConst()<<endl;??
- //??cout?<<?"----------------------"?<<endl;??
- ??
- ????cout?<<?"----------------------"?<<endl;??
- ????//請別在你的應用程序中使用getConst2??
- ????cout?<<?"DLL_API?getConst1:?"<<getConst1()<<endl;??
- ????cout?<<?"????????getConst2:?"<<getConst2()<<endl;??
- //??cout?<<?"DLL_API?getConst3:?"<<getConst3()<<endl;??
- ????cout?<<?"----------------------"?<<endl;??
- ??
- //??cout?<<?"others:?"?<<?others(6)<<endl;??
- //??cout?<<?"others:?"?<<?others(16)<<endl;??
- //??cout?<<?"----------------------"?<<endl;??
- ??
- ????cout?<<?"please?press?Enter?exit."<<endl;??
- ????getchar();??
- ????return?0;??
- }??
運行結果為:
- ----------------------??
- sd.add:?3+5=8??
- sd.getConst():?10??
- psd->add:?5+5=10??
- psd->getConst():???
- ----------------------??
- SimpleDll::sub:?2-1=1??
- ----------------------??
- zdd::number:?5??
- changed?zdd::number:?10??
- ----------------------??
- sdd.add:?6+8=14??
- psdd->add:?6+8=14??
- psdd1->add:?6+8=14??
- ??
- sdd.getConst():?10??
- psdd.getConst():?10??
- psdd1.getConst():?10??
- ----------------------??
- zdd::Add:?7+8=15??
- ----------------------??
- create->add:?2+3=5??
- create->getConst():?10??
- ----------------------??
- ----------------------??
- DLL_API?getConst1:?100??
- ????????getConst2:?100??
- ----------------------??
- please?press?Enter?exit.??
可將生成的可執行文件和應用程序拷出到同一目錄下,通過更改方法getConst1,getConst2,體會dllexport和dllimport的作用。