青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

醬壇子

專注C++技術(shù) 在這里寫下自己的學(xué)習(xí)心得 感悟 和大家討論 共同進(jìn)步(歡迎批評!!!)

  C++博客 :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
  66 Posts :: 16 Stories :: 236 Comments :: 0 Trackbacks

公告

王一偉 湖南商學(xué)院畢業(yè) 電子信息工程專業(yè)

常用鏈接

留言簿(19)

我參與的團(tuán)隊(duì)

搜索

  •  

積分與排名

  • 積分 - 389905
  • 排名 - 64

最新隨筆

最新評論

閱讀排行榜

評論排行榜

雖然能用DLL實(shí)現(xiàn)的東西都可以用COM來實(shí)現(xiàn),但DLL的優(yōu)點(diǎn)確實(shí)不少,它更容易創(chuàng)建。本文將討論如何利用MFC來創(chuàng)建不同類型的DLL,以及如何使用他們。

一、DLL的不同類型
??? 使用MFC可以生成兩種類型的DLL:MFC擴(kuò)展DLL和常規(guī)DLL。常規(guī)DLL有可以分為動(dòng)態(tài)連接和靜態(tài)連接。Visual C++還可以生成WIN32 DLL,但不是這里討論的主要對象。
1、MFC擴(kuò)展DLL
?? 每個(gè)DLL都有某種類型的接口:變量、指針、函數(shù)、客戶程序訪問的類。它們的作用是讓客戶程序使用DLL,MFC擴(kuò)展DLL可以有C++的接口。也就是它可以導(dǎo)出C++類給客戶端。導(dǎo)出的函數(shù)可以使用C++/MFC數(shù)據(jù)類型做參數(shù)或返回值,導(dǎo)出一個(gè)類時(shí)客戶端能創(chuàng)建類對象或者派生這個(gè)類。同時(shí),在DLL中也可以使用DLL和MFC。
?? Visual C++使用的MFC類庫也是保存在一個(gè)DLL中,MFC擴(kuò)展DLL動(dòng)態(tài)連接到MFC代碼庫的DLL,客戶程序也必須要?jiǎng)討B(tài)連接到MFC代碼庫的DLL。(這里談到的兩個(gè)DLL,一個(gè)是我們自己編寫的DLL,一個(gè)裝MFC類庫的DLL)現(xiàn)在MFC代碼庫的DLL也存在多個(gè)版本,客戶程序和擴(kuò)展DLL都必須使用相同版本的MFC代碼DLL。所以為了讓MFC擴(kuò)展DLL能很好的工作,擴(kuò)展DLL和客戶程序都必須動(dòng)態(tài)連接到MFC代碼庫DLL。而這個(gè)DLL必須在客戶程序運(yùn)行的計(jì)算機(jī)上。
2、常規(guī)DLL
?? 使用MFC擴(kuò)展DLL的一個(gè)問題就是DLL僅能和MFC客戶程序一起工作,如果需要一個(gè)使用更廣泛的DLL,最好采用常規(guī)DLL,因?yàn)樗皇躆FC的某些限制。常規(guī)DLL也有缺點(diǎn):它不能和客戶程序發(fā)送指針或MFC派生類和對象的引用。一句話就是常規(guī)DLL和客戶程序的接口不能使用MFC,但在DLL和客戶程序的內(nèi)部還是可以使用MFC。
?? 當(dāng)在常規(guī)DLL的內(nèi)部使用MFC代碼庫的DLL時(shí),可以是動(dòng)態(tài)連接/靜態(tài)連接。如果是動(dòng)態(tài)連接,也就是常規(guī)DLL需要的MFC代碼沒有構(gòu)建到DLL中,這種情況有點(diǎn)和擴(kuò)展DLL類似,在DLL運(yùn)行的計(jì)算機(jī)上必須要MFC代碼庫的DLL。如果是靜態(tài)連接,常規(guī)DLL里面已經(jīng)包含了需要的MFC代碼,這樣DLL的體積將比較大,但它可以在沒有MFC代碼庫DLL的計(jì)算機(jī)上正常運(yùn)行。

二、建立DLL
??? 利用Visual C++提供的向?qū)Чδ芸梢院苋菀捉⒁粋€(gè)不完成任何實(shí)質(zhì)任務(wù)的DLL,這里就不多講了,主要的任務(wù)是如何給DLL添加功能,以及在客戶程序中利用這個(gè)DLL
1、導(dǎo)出類
?? 用向?qū)Ы⒑每蚣芎螅涂梢蕴砑有枰獙?dǎo)出類的.cpp .h文件到DLL中來,或者用向?qū)?chuàng)建C++ Herder File/C++ Source File。為了能導(dǎo)出這個(gè)類,在類聲明的時(shí)候要加“_declspec(dllexport)”,如:
class _declspec(dllexport) CMyClass
{
???? ...//聲明
}
如果創(chuàng)建的MFC擴(kuò)展DLL,可以使用宏:AFX_EXT_CLASS:
class AFX_EXT_CLASS CMyClass
{
???? ...//聲明
}
這樣導(dǎo)出類的方法是最簡單的,也可以采用.def文件導(dǎo)出,這里暫不詳談。
2、導(dǎo)出變量、常量、對象
?? 很多時(shí)候不需要導(dǎo)出一個(gè)類,可以讓DLL導(dǎo)出一個(gè)變量、常量、對象,導(dǎo)出它們只需要進(jìn)行簡單的聲明:_declspec(dllexport) int MyInt;
? _declspec(dllexport) extern const COLORREF MyColor=RGB(0,0,0);
? _declspec(dllexport) CRect rect(10,10,20,20);
要導(dǎo)出一個(gè)常量時(shí)必須使用關(guān)鍵字extern,否則會(huì)發(fā)生連接錯(cuò)誤。
注意:如果客戶程序識別這個(gè)類而且有自己的頭文件,則只能導(dǎo)出一個(gè)類對象。如果在DLL中創(chuàng)建一個(gè)類,客戶程序不使用頭文件就無法識別這個(gè)類。
? 當(dāng)導(dǎo)出一個(gè)對象或者變量時(shí),載入DLL的每個(gè)客戶程序都有一個(gè)自己的拷貝。也就是如果兩個(gè)程序使用的是同一個(gè)DLL,一個(gè)應(yīng)用程序所做的修改不會(huì)影響另一個(gè)應(yīng)用程序。
? 我們在導(dǎo)出的時(shí)候只能導(dǎo)出DLL中的全局變量或?qū)ο螅荒軐?dǎo)出局部的變量和對象,因?yàn)樗鼈冞^了作用域也就不存在了,那樣DLL就不能正常工作。如:
MyFunction()
{
????? _declspec(dllexport) int MyInt;
????? _declspec(dllexport) CMyClass object;
}
3、導(dǎo)出函數(shù)
導(dǎo)出函數(shù)和導(dǎo)出變量/對象類似,只要把_declspec(dllexport)加到函數(shù)原型開始的位置:
_declspec(dllexport) int MyFunction(int);
如果是常規(guī)DLL,它將和C寫的程序使用,聲明方式如下:
extern "c" _declspec(dllexport) int MyFunction(int);
實(shí)現(xiàn):
extern "c" _declspec(dllexport) int MyFunction(int x)
{
???? ...//操作
}
如果創(chuàng)建的是動(dòng)態(tài)連接到MFC代碼庫DLL的常規(guī)DLL,則必須插入AFX_MANAGE_STATE作為導(dǎo)出函數(shù)的首行,因此定義如下:
extern "c" _declspec(dllexport) int MyFunction(int x)
{
???? AFX_MANAGE_STATE(AfxGetStaticModuleState());
???? ...//操作
}
有時(shí)候?yàn)榱税踩鹨姡诿總€(gè)常規(guī)DLL里都加上,也不會(huì)有任何問題,只是在靜態(tài)連接的時(shí)候這個(gè)宏無效而已。這是導(dǎo)出函數(shù)的方法,記住只有MFC擴(kuò)展DLL才能讓參數(shù)和返回值使用MFC的數(shù)據(jù)類型。
4、導(dǎo)出指針
導(dǎo)出指針的方式如下:
_declspec(dllexport) int *pint;
_declspec(dllexport) CMyClass object = new CMyClass;
如果聲明的時(shí)候同時(shí)初始化了指針,就需要找到合適的地方類釋放指針。在擴(kuò)展DLL中有個(gè)函數(shù)DllMain()。(注意函數(shù)名中的兩個(gè)l要是小寫字母),可以在這個(gè)函數(shù)中處理指針:
# include "MyClass.h"
_declspec(dllexport) CMyClass *pobject = new CMyClass;
DllMain(HINSTANCE hInstance,DWORD dwReason,LPVOID lpReserved)
{
??? if(dwReason == DLL_PROCESS_ATTACH)
??? {
??????? .....//
??? }
??? else if(dwReason == DLL_PROCESS_DETACH)
??? {
??????? delete pobject;
??? }
}
常規(guī)DLL有一個(gè)從CWinApp派生的類對象處理DLL的開和關(guān),可以使用類向?qū)砑覫nitInstance/ExitInstance函數(shù)。
int CMyDllApp::ExitInstance()
{
??? delete pobject;
??? return CWinApp::ExitInstance();
}

三、在客戶程序中使用DLL
??? 編譯一個(gè)DLL時(shí)將創(chuàng)建兩個(gè)文件.dll文件和.lib文件。首先將這兩個(gè)文件復(fù)制到客戶程序項(xiàng)目的文件夾里,這里需要注意DLL和客戶程序的版本問題,盡量使用相同的版本,都使用RELEASE或者都是DEBUG版本。
?? 接著就需要在客戶程序中設(shè)置LIB文件,打開Project Settings--->Link--->Object/library Modules中輸入LIB的文件名和路徑。如:Debug/SampleDll.lib。除了DLL和LIB文件外,客戶程序需要針對導(dǎo)出類、函數(shù)、對象和變量的頭文件,現(xiàn)在進(jìn)行導(dǎo)入添加的關(guān)鍵字就是:_declspec(dllimport),如:
_declspec(dllimport) int MyFunction(int);
_declspec(dllimport) int MyInt;
_declspec(dllimport) CMyClass object;
extern "C" _declspec(dllimport) int MyFunction(int);
在有的時(shí)候?yàn)榱藢?dǎo)入類,要把相應(yīng)類的頭文件添加到客戶程序中,不同的是要修改類聲明的標(biāo)志:
class _declspec(dllimport) CMyClass,如果創(chuàng)建的是擴(kuò)展DLL,兩個(gè)位置都是:
class AFX_EXT_CLASS CMyClass。


使用DLL的一個(gè)比較嚴(yán)重的問題就是編譯器之間的兼容性問題。不同的編譯器對c++函數(shù)在二進(jìn)制級別的實(shí)現(xiàn)方式是不同的。所以對基于C++的DLL,如果編譯器不同就有很麻煩的。如果創(chuàng)建的是MFC擴(kuò)展DLL,就不會(huì)存在問題,因?yàn)樗荒鼙粍?dòng)態(tài)連接到MFC的客戶應(yīng)用程序。這里不是本文討論的重點(diǎn)。

一、重新編譯問題
我們先來看一個(gè)在實(shí)際中可能遇到的問題:
??? 比如現(xiàn)在建立好了一個(gè)DLL導(dǎo)出了CMyClass類,客戶也能正常使用這個(gè)DLL,假設(shè)CMyClass對象的大小為30字節(jié)。如果我們需要修改DLL中的CMyClass類,讓它有相同的函數(shù)和成員變量,但是給增加了一個(gè)私有的成員變量int類型,現(xiàn)在CMyClass對象的大小就是34字節(jié)了。當(dāng)直接把這個(gè)新的DLL給客戶使用替換掉原來30字節(jié)大小的DLL,客戶應(yīng)用程序期望的是30字節(jié)大小的對象,而現(xiàn)在卻變成了一個(gè)34字節(jié)大小的對象,糟糕,客戶程序出錯(cuò)了。
??? 類似的問題,如果不是導(dǎo)出CMyClass類,而在導(dǎo)出的函數(shù)中使用了CMyClass,改變對象的大小仍然會(huì)有問題的。這個(gè)時(shí)候修改這個(gè)問題的唯一辦法就是替換客戶程序中的CMyClass的頭文件,全部重新編譯整個(gè)應(yīng)用程序,讓客戶程序使用大小為34字節(jié)的對象。
??? 這就是一個(gè)嚴(yán)重的問題,有的時(shí)候如果沒有客戶程序的源代碼,那么我們就不能使用這個(gè)新的DLL了。

二、解決方法??
?為了能避免重新編譯客戶程序,這里介紹兩個(gè)方法:(1)使用接口類。(2)使用創(chuàng)建和銷毀類的靜態(tài)函數(shù)。
1、使用接口類
?? 接口類的也就是創(chuàng)建第二個(gè)類,它作為要導(dǎo)出類的接口,所以在導(dǎo)出類改變時(shí),也不需要重新編譯客戶程序,因?yàn)榻涌陬悰]有發(fā)生變化。
?? 假設(shè)導(dǎo)出的CMyClass類有兩個(gè)函數(shù)FunctionA FunctionB。現(xiàn)在創(chuàng)建一個(gè)接口類CMyInte***ce,下面就是在DLL中的CMyInte***ce類的頭文件的代碼:
# include "MyClass.h"
class _declspec(dllexport) CMyInte***ce
{
???? CMyClass *pmyclass;
???? CMyInte***ce();
???? ~CMyInte***ce();
? public:
???? int FunctionA(int);
???? int FunctionB(int);
};
而在客戶程序中的頭文件稍不同,不需要INCLUDE語句,因?yàn)榭蛻舫绦驔]有它的拷貝。相反,使用一個(gè)CMyClass的向前聲明,即使沒有頭文件也能編譯:
class _declspec(dllexport) CMyInte***ce
{
???? class CMyClass;//向前聲明
???? CMyClass *pmyclass;
???? CMyInte***ce();
???? ~CMyInte***ce();
? public:
???? int FunctionA(int);
???? int FunctionB(int);
};
在DLL中的CMyInte***ce的實(shí)現(xiàn)如下:
CMyInte***ce::CMyInte***ce()
{
????? pmyclass = new CMyClass();
}
CMyInte***ce::~CMyInte***ce()
{
???? delete pmyclass;
}
int CMyInte***ce::FunctionA()
{
???? return pmyclass->FunctionA();
}
int CMyInte***ce::FunctionB()
{
???? return pmyclass->FunctionB();???
}
.....
對導(dǎo)出類CMyClass的每個(gè)成員函數(shù),CMyInte***ce類都提供自己的對應(yīng)的函數(shù)。客戶程序與CMyClass沒有聯(lián)系,這樣任意改CMyClass也不會(huì)有問題,因?yàn)镃MyInte***ce類的大小沒有發(fā)生變化。即使為了能訪問CMyClass中的新增變量而給CMyInte***ce類加了函數(shù)也不會(huì)有問題的。
?? 但是這種方法也存在明顯的問題,對導(dǎo)出類的每個(gè)函數(shù)和成員變量都要對應(yīng)實(shí)現(xiàn),有的時(shí)候這個(gè)接口類會(huì)很龐大。同時(shí)增加了客戶程序調(diào)用所需要的時(shí)間。增加了程序的開銷。

2、使用靜態(tài)函數(shù)
?? 還可以使用靜態(tài)函數(shù)來創(chuàng)建和銷毀類對象。創(chuàng)建一個(gè)導(dǎo)出類的時(shí)候,增加兩個(gè)靜態(tài)的公有函數(shù)CreateMe()/DestroyMe(),頭文件如下:
class _declspec(dllexport) CMyClass
{
???? CMyClass();
???? ~CMyClass();
? public:
???? static CMyClass *CreateMe();
???? static void DestroyMe(CMyClass *ptr);
};
實(shí)現(xiàn)函數(shù)就是:
CMyClass * CMyClass::CMyClass()
{
????? return new CMyClass;
}
void CMyClass::DestroyMe(CMyClass *ptr)
{
????? delete ptr;
}
然后象其他類一樣導(dǎo)出CMyClass類,這個(gè)時(shí)候在客戶程序中使用這個(gè)類的方法稍有不同了。如若想創(chuàng)建一個(gè)CMyClass對象,就應(yīng)該是:
CMyClass x;
CMyClass *ptr = CMyClass::CreateMe();
在使用完后刪除:
CMyClass::DestroyMe(ptr);
posted on 2006-10-16 08:42 @王一偉 閱讀(891) 評論(0)  編輯 收藏 引用 所屬分類: 1. MFC

只有注冊用戶登錄后才能發(fā)表評論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国产欧美一级| 玖玖在线精品| 欧美成人免费网站| 久久激情五月丁香伊人| 欧美精品成人| 欧美高清在线精品一区| 国产婷婷色一区二区三区| 亚洲精品日韩一| 亚洲国产精品久久久久秋霞不卡| 亚洲一区免费视频| 亚洲人成在线观看| 久久久噜噜噜久久狠狠50岁| 午夜激情亚洲| 国产精品久久久久毛片软件| 最新成人在线| 亚洲经典一区| 鲁鲁狠狠狠7777一区二区| 久久精品一二三| 国产精品无码永久免费888| 日韩一区二区精品葵司在线| 亚洲精品一区二区三区四区高清| 久久精品国产精品| 久久久久久亚洲精品中文字幕| 国产精品多人| 亚洲尤物在线视频观看| 亚洲欧美日韩国产中文| 国产精品久久久久久久app| 亚洲最新在线视频| 亚洲欧美一区二区激情| 国产精品高清网站| 亚洲视频免费看| 亚洲一区二区三区中文字幕在线 | 欧美一级成年大片在线观看| 午夜久久99| 国产美女搞久久| 欧美一区二区大片| 另类春色校园亚洲| 亚洲国产精品激情在线观看| 老鸭窝毛片一区二区三区| 亚洲高清视频一区二区| 日韩亚洲国产欧美| 国产精品扒开腿爽爽爽视频| 亚洲淫性视频| 久久只精品国产| 亚洲高清在线观看一区| 欧美激情一二三区| 亚洲一级黄色| 六月婷婷久久| 在线视频亚洲欧美| 国产精品网站视频| 久久亚洲国产精品日日av夜夜| 亚洲国产成人久久| 亚洲女女做受ⅹxx高潮| 激情亚洲成人| 欧美日韩亚洲一区二区三区在线| 亚洲专区在线| 欧美电影免费观看大全| 一区二区三区高清| 国产真实乱子伦精品视频| 久久综合图片| 一区二区三区日韩精品视频| 久久精品国产亚洲5555| 亚洲精选久久| 国产亚洲a∨片在线观看| 免费视频亚洲| 亚洲欧美在线免费| 亚洲精品乱码久久久久久蜜桃麻豆| 亚洲欧美日韩国产| 亚洲国产成人精品久久| 国产精品乱看| 欧美大片专区| 欧美一区高清| 一本大道久久a久久综合婷婷 | 99精品视频一区| 麻豆freexxxx性91精品| 亚洲一区二区三区免费视频| 亚洲第一精品福利| 国产女主播在线一区二区| 欧美国产日韩在线| 久久国产天堂福利天堂| 一本色道久久99精品综合| 蜜臀91精品一区二区三区| 午夜精品偷拍| 在线视频亚洲一区| 亚洲国产精品精华液网站| 国产欧美日韩视频在线观看| 欧美日韩在线高清| 欧美电影免费| 久久一区激情| 久久精品国产99| 欧美一二三区在线观看| 一二三区精品| 亚洲毛片视频| 亚洲黄色免费电影| 女人色偷偷aa久久天堂| 久久精品亚洲乱码伦伦中文| 亚洲欧美日韩在线观看a三区| 99国产精品一区| 91久久精品美女高潮| 影视先锋久久| 亚洲第一中文字幕| 国产在线乱码一区二区三区| 国产女人水真多18毛片18精品视频| 欧美午夜www高清视频| 欧美日本三级| 欧美日韩少妇| 欧美日韩一区二区在线观看| 欧美日本一区| 欧美日本在线播放| 欧美人与禽猛交乱配| 欧美伦理一区二区| 欧美日本在线播放| 欧美三日本三级少妇三99 | 欧美不卡高清| 免费成人黄色| 欧美激情综合网| 欧美精品福利视频| 欧美日韩性生活视频| 欧美视频精品在线| 国产精品日韩欧美综合| 国产毛片精品视频| 黑丝一区二区| 亚洲高清一二三区| 99re6这里只有精品| 亚洲小说欧美另类社区| 亚洲欧美日韩精品久久| 久久9热精品视频| 久久久久久久综合色一本| 免费中文日韩| 亚洲精品乱码| 亚洲欧美日韩一区| 久久狠狠亚洲综合| 欧美大片在线观看| 国产精品成av人在线视午夜片| 国产精品视频久久久| 国语自产精品视频在线看| 亚洲激情成人在线| 亚洲一区二区欧美| 久久精品国产亚洲aⅴ| 欧美国产日本韩| 在线午夜精品| 久久久噜噜噜久久中文字幕色伊伊| 欧美成人午夜影院| 国产精品家庭影院| 在线播放国产一区中文字幕剧情欧美| 亚洲人成在线观看网站高清| 亚洲一级黄色| 免费观看30秒视频久久| 99精品国产在热久久下载| 久久高清国产| 欧美色一级片| 亚洲国内高清视频| 午夜精品久久久久久久久久久久| 母乳一区在线观看| 这里只有精品丝袜| 免费在线播放第一区高清av| 国产精品入口福利| 亚洲精品免费一区二区三区| 欧美一区二区三区在线播放| 亚洲国产精品久久精品怡红院 | 欧美一级淫片播放口| 欧美激情一区二区久久久| 国产乱码精品| aa亚洲婷婷| 欧美a一区二区| 欧美怡红院视频| 国产精品久久久久三级| 日韩视频在线观看国产| 久久久久久久性| 亚洲一卡二卡三卡四卡五卡| 欧美69视频| 影音先锋久久久| 久久久久久久波多野高潮日日| 野花国产精品入口| 欧美精品一区二区三区在线看午夜 | 亚洲调教视频在线观看| 欧美成人一二三| 久久国产精品电影| 国产精品一二三四| 亚洲一区在线视频| 亚洲国产三级网| 久久综合成人精品亚洲另类欧美| 国产亚洲成av人在线观看导航| 亚洲午夜激情网页| 最新国产精品拍自在线播放| 久久视频在线视频| 一区二区三区在线不卡| 久久久精品视频成人| 亚洲欧美一区二区视频| 国产精品美女久久久久久免费 | 亚洲一区免费看| 国产精品视频| 午夜在线精品偷拍| 亚洲一二三区精品| 国产精品高清网站| 亚洲欧美国产一区二区三区| 一区二区三区四区国产| 欧美日韩亚洲综合一区| 亚洲视频在线视频| 在线视频你懂得一区|