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

白駒過(guò)隙
學(xué)而不思則罔,思而不學(xué)則怠
posts - 4,  comments - 3,  trackbacks - 0

?? 還有一種方法可以顯式導(dǎo)出類成員函數(shù),就是采用虛函數(shù)表的方法。 COM 就是這樣做的。當(dāng)在類中聲明一組虛函數(shù)的時(shí)候, 編譯器會(huì)創(chuàng)建一個(gè)虛函數(shù)表,將各虛函數(shù)的地址按聲明的順序放入其中。當(dāng)一個(gè)類對(duì)象被創(chuàng)建時(shí),它的前四個(gè)字節(jié)是一個(gè)指針,指向這個(gè)虛函數(shù)表。所以,修改以上的代碼:

//CTry.h

??? virtual void print() ; // 將這個(gè)成員函數(shù)聲明為虛函數(shù)

TRY_API CTry* createObject() ; // 聲明一個(gè)全局函數(shù),創(chuàng)建一個(gè) Ctry 對(duì)象的實(shí)例

//CTry.cpp

CTry *createObject()

{

??? return new CTry() ;

}

?

在測(cè)試工程中,顯式導(dǎo)出該全局函數(shù),并通過(guò)它調(diào)用類成員函數(shù)。

typedef CTry* (*Fn_FunType)() ;

Fn_FunType pFun=(Fn_FunType)::GetProcAddress(hInstance ,"?createObject@@YAPAVCTry@@XZ") ;

CTry * pTry = pFun() ;

pTry ->print() ;

delete pTry ;


?? 這個(gè)方法雖然同樣能達(dá)到顯式導(dǎo)出類成員函數(shù)的目的。但是上面的方法有個(gè)缺點(diǎn),就是在DLLnew 出來(lái)的對(duì)象,卻要放到客戶端釋放。因?yàn)榭蛻舳瞬⒉恢?/span>DLL中的實(shí)現(xiàn)方法,很可能會(huì)不知道釋放這個(gè)對(duì)象,從而造成內(nèi)存泄露。<<Effiective C++>>中明文規(guī)定禁止這樣做。

?

? 現(xiàn)在要找一個(gè)方法可以把回收內(nèi)存的任務(wù)交 DLL 自己來(lái)處理。有沒(méi)有這樣一個(gè)方法呢?當(dāng)然有,它就是引用計(jì)數(shù)。引用計(jì)數(shù)是一個(gè)簡(jiǎn)單的垃圾回收機(jī)制,它的原理很簡(jiǎn)單,組件內(nèi)部維護(hù)著一個(gè)引用計(jì)數(shù)的數(shù)值,當(dāng)用戶從組件取得一個(gè)接口時(shí),該數(shù)值 +1 ,當(dāng)用戶使用完這個(gè)接口,并釋放該接口時(shí),該數(shù)值 -1 ,當(dāng)該數(shù)值為 0 時(shí),組件將自己從內(nèi)存中刪除。下面是采用了引用計(jì)數(shù)的 DLL 實(shí)現(xiàn)方法。


#ifdef?TRY_EXPORTS
#define ?TRY_API?__declspec(dllexport)
#else
#define ?TRY_API?__declspec(dllimport)
#endif
#include?
< iostream >
using ? namespace ?std;

// ?此類是從?Try.dll?導(dǎo)出的
class ??CTry? {
public :
????friend?TRY_API?CTry
* ?createObject()?;

????
virtual ?? void ?print()?;

????
virtual ? void ?addRef()?;

????
virtual ? void ?removeRef()?;
protected :
????
int ?refCount?;

????
// 不允許通過(guò)構(gòu)造函數(shù)初始化對(duì)象
????CTry( void )?;
????
????
virtual ? ~ CTry()?;


????
// 不允許相互賦值,這里面細(xì)節(jié)太多,懶得去分析:D
????CTry(CTry? & ths)?;

????CTry
* ? operator = ?( const ?CTry & ?ths?)?;
????
}
;

extern ?TRY_API? int ?nTry;

TRY_API?
int ?fnTry( void );
?
TRY_API?CTry
* ?createObject()?;

// ?Try.cpp?:?定義?DLL?應(yīng)用程序的入口點(diǎn)。
//

#include?
" stdafx.h "
#include?
" Try.h "


#ifdef?_MANAGED
#pragma?managed(push,?off)
#endif

BOOL?APIENTRY?DllMain(?HMODULE?hModule,
???????????????????????DWORD??ul_reason_for_call,
???????????????????????LPVOID?lpReserved
?????????????????????)
{
????
switch ?(ul_reason_for_call)
????
{
????
case ?DLL_PROCESS_ATTACH:
????
case ?DLL_THREAD_ATTACH:
????
case ?DLL_THREAD_DETACH:
????
case ?DLL_PROCESS_DETACH:
????????
break ;
????}

????
return ?TRUE;
}


#ifdef?_MANAGED
#pragma?managed(pop)
#endif

// ?這是導(dǎo)出變量的一個(gè)示例
TRY_API? int ?nTry? = ? 0 ;

// ?這是導(dǎo)出函數(shù)的一個(gè)示例。
TRY_API? int ?fnTry( void )
{
????
return ? 42 ;
}


// ?這是已導(dǎo)出類的構(gòu)造函數(shù)。
// ?有關(guān)類定義的信息,請(qǐng)參閱?Try.h

void ?CTry::print()
{
????cout
<< " CTry " << endl;
}


?CTry?
* createObject()
?
{
?????CTry?
* pTry? = ? new ?CTry()?;
?????pTry
-> addRef()?;
?????
return ?pTry?;
?}


?
void ?CTry::removeRef()
?
{
?????
if ?( -- refCount? == ? 0 )
?????
{
?????????delete?
this ?; // 刪除自己
?????}

?}


?
void ?CTry::addRef()
?
{
?????
++ refCount?;
?}


?CTry::CTry()
?
{
?????refCount?
= ? 0 ?;
?}


?CTry::
~ CTry()
?
{

?}

?CTry::CTry(CTry?
& ths)
?
{

?}


?CTry?
* CTry:: operator ? = ( const ?CTry? & ths)
?
{
?????
return ?NULL;
?}

?

? 上面的方法中,用戶不能通過(guò)構(gòu)造函數(shù)來(lái)實(shí)例化一個(gè)對(duì)象,必須通過(guò) createObject 接口才能實(shí)例化對(duì)象,當(dāng)用戶使用完這個(gè)對(duì)象時(shí)必須調(diào)用 removeRef() 接口。代碼如下:

#include? " stdafx.h "
#include?
< iostream >
#include?
" Try.h "
using ? namespace ?std;

typedef?CTry
* ?( * Fn_FunType)()?;

int ?main()
{

????HINSTANCE?hInstance?
= ? 0 ;
????hInstance?
= ?LoadLibrary( " Try.dll " )?;
????
if ?(hInstance)
????
{
????????Fn_FunType?pFun?
= ?(Fn_FunType)::GetProcAddress(hInstance?, " ?createObject@@YAPAVCTry@@XZ " )?;

????????
if ?(pFun)
????????
{
????????????
// (pTry->*pFun)()?;
????????????CTry * ?pTry? = ?pFun()?;
????????????pTry
-> print()?;
????????????pTry
-> removeRef();
????????}

????}

????system(
" pause " )?;
????
return ? 0 ?;
}



? 當(dāng)然上面只是我為了方便測(cè)試而寫的一個(gè)簡(jiǎn)單的例子,還不完善。引用計(jì)數(shù)還有很多細(xì)節(jié)和注意事項(xiàng)。具體請(qǐng)看《more effective c++》第29項(xiàng)。

?

關(guān)于名字修飾約定

?

?? 前面代碼我都是通過(guò)編譯器中的修飾名來(lái)調(diào)用相應(yīng)的函數(shù)的,修飾名是編譯器在編譯函數(shù)定義或者原型時(shí)生成的字符串。比如 "?createObject@@YAPAVCTry@@XZ" 就是 CTry::createObject 的修飾名。

名字修飾約定隨調(diào)用約定和編譯種類 (C C++) 的不同而變化。函數(shù)名修飾約定隨編譯種類和調(diào)用約定的不同而不同,下面分別說(shuō)明。

A C 編譯時(shí)函數(shù)名修飾約定規(guī)則:

__stdcall 調(diào)用約定在輸出函數(shù)名前加上一個(gè)下劃線前綴,后面加上一個(gè) "@" 符號(hào)和其參數(shù)的字節(jié)數(shù),格式為 _functionname@number

__cdecl 調(diào)用約定僅在輸出函數(shù)名前加上一個(gè)下劃線前綴,格式為 _functionname

__fastcall 調(diào)用約定在輸出函數(shù)名前加上一個(gè) "@" 符號(hào),后面也是一個(gè) "@" 符號(hào)和其參數(shù)的字節(jié)數(shù),格式為 @functionname@number

它們均不改變輸出函數(shù)名中的字符大小寫,這和 PASCAL 調(diào)用約定不同, PASCAL 約定輸出的函數(shù)名無(wú)任何修飾且全部大寫。

B C++ 編譯時(shí)函數(shù)名修飾約定規(guī)則:

__stdcall 調(diào)用約定:

1 、以 "?" 標(biāo)識(shí)函數(shù)名的開(kāi)始,后跟函數(shù)名;

2 、函數(shù)名后面以 "@@YG" 標(biāo)識(shí)參數(shù)表的開(kāi)始,后跟參數(shù)表;

3 、參數(shù)表以代號(hào)表示:

X--void

D--char

E--unsigned char

F--short

H--int

I--unsigned int

J--long

K--unsigned long

M--float

N--double

_N--bool

....

PA-- 表示指針,后面的代號(hào)表明指針類型,如果相同類型的指針連續(xù)出現(xiàn),以 "0" 代替,一個(gè) "0" 代表一次重復(fù);

4 、參數(shù)表的第一項(xiàng)為該函數(shù)的返回值類型,其后依次為參數(shù)的數(shù)據(jù)類型 , 指針標(biāo)識(shí)在其所指數(shù)據(jù)類型前;

5 、參數(shù)表后以 "@Z" 標(biāo)識(shí)整個(gè)名字的結(jié)束,如果該函數(shù)無(wú)參數(shù),則以 "Z" 標(biāo)識(shí)結(jié)束。

其格式為 "?functionname@@YG*****@Z" "?functionname@@YG*XZ" ,例如

????????? int Test1 char *var1,unsigned long ----- ?Test1@@YGHPADK@Z

????????? void Test2 () ?????????????????????? ----- ?Test2@@YGXXZ

?

__cdecl 調(diào)用約定:

規(guī)則同上面的 _stdcall 調(diào)用約定,只是參數(shù)表的開(kāi)始標(biāo)識(shí)由上面的 "@@YG" 變?yōu)?/span> "@@YA"

__fastcall 調(diào)用約定:

規(guī)則同上面的 _stdcall 調(diào)用約定,只是參數(shù)表的開(kāi)始標(biāo)識(shí)由上面的 "@@YG" 變?yōu)?/span> "@@YI" VC++ 對(duì)函數(shù)的省缺聲明是 "__cedcl", 將只能被 C/C++ 調(diào)用 .

?

?? 通常我們希望我們的 DLL 中的導(dǎo)出函數(shù)名能夠更易被識(shí)別(用戶使用才會(huì)更方便),也就是說(shuō) DLL 應(yīng)該編譯出無(wú)修飾的 C 函數(shù)名,而不復(fù)雜的修飾名。所以當(dāng)使用 C++ 文件來(lái)創(chuàng)建 DLL 時(shí)應(yīng)該使用 extern “c” 來(lái)修飾導(dǎo)出函數(shù)和變量。實(shí)際上 VS 編譯器已經(jīng)為我們準(zhǔn)備了一個(gè)宏 EXTERN_C 用來(lái)代替 extern “c” 。修改以上的代碼如下:

EXTERN_C TRY_API int nTry;

EXTERN_C TRY_API int fnTry(void);

生成 DLL ,用 depens 工具查看,他們已經(jīng)變成了如下模樣:

?

這樣在客戶端就可以通過(guò)函數(shù)名去調(diào)用它們。但是 EXTERN_C 宏卻沒(méi)辦法修飾類成員函數(shù),

如果像全局函數(shù)那樣修飾類成員函數(shù),編譯無(wú)法通過(guò)。用 .DEF 文件可以解決這個(gè)問(wèn)題。

?

關(guān)于 .def 文件

模塊定義 (.def) 文件是包含一個(gè)或多個(gè)描述 DLL 各種屬性的 Module 語(yǔ)句的文本文件。

def 文件包含下列模塊定義語(yǔ)句:

1. 文件中的第一個(gè)語(yǔ)句必須是 LIBRARY 語(yǔ)句。此語(yǔ)句將 .def 文件標(biāo)識(shí)為屬于 DLL LIBRARY 語(yǔ)句的后面是 DLL 的名稱。鏈接器將此名稱放到 DLL 的導(dǎo)入庫(kù)中。

2. ?EXPORTS 語(yǔ)句列出被導(dǎo)出函數(shù)的名字;將要輸出的函數(shù)修飾名羅列在 EXPORTS 之下,這個(gè)名字必須與定義函數(shù)的名字完全一致,如此就得到一個(gè)沒(méi)有任何修飾的函數(shù)名了。

3.? 可以使用 DESCRIPTION 語(yǔ)句描述 DLL 的用途 ( 此句可選 )

4.?? ";" 對(duì)一行進(jìn)行注釋 ( 可選 )

?

創(chuàng)建一 .DEF 文件,命名為 export.def ,用來(lái)修飾 CTry::print 函數(shù),如下:

LIBRARY??? "Try"

EXPORTS

print????? =????? ?print@CTry@@UAEXXZ? PRIVATE

?

DLL 工程屬性 -> 鏈接器 -> 輸入 -> 模塊定義文件中將 export.def 添加進(jìn)去。這樣就可以直接通過(guò)函數(shù)名來(lái)顯式調(diào)用類成員函數(shù)了。下面是 DLL depens 工具中顯示的情況。

?

參考資料:

windows 核心編程》

programming windows

《微軟 DLL 專題》

posted on 2009-03-08 17:01 隙中駒 閱讀(548) 評(píng)論(1)  編輯 收藏 引用

FeedBack:
# re: DLL學(xué)習(xí)筆記 3
2009-03-12 09:32 | guest
圖片的路徑是“e:/1.bmp”,你本地應(yīng)該可以顯示,但是其他地方都看不到圖了。
請(qǐng)修改圖片鏈接。  回復(fù)  更多評(píng)論
  

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



<2009年3月>
22232425262728
1234567
891011121314
15161718192021
22232425262728
2930311234

常用鏈接

留言簿(2)

隨筆檔案(4)

文章分類(1)

文章檔案(1)

友情鏈接

最新隨筆

搜索

  •  

最新評(píng)論

閱讀排行榜

評(píng)論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            亚洲欧美激情视频| 欧美乱人伦中文字幕在线| 欧美在线视频日韩| av不卡在线| 精品91久久久久| 国产精品嫩草99a| 欧美伦理在线观看| 久久综合久久88| 久久亚洲精品一区| 久久在线视频| 另类欧美日韩国产在线| 久久天堂国产精品| 亚洲欧美另类在线| 欧美成人蜜桃| 欧美激情四色| 欧美日韩免费观看一区二区三区 | 亚洲一区二区视频| 亚洲图片欧美日产| 亚洲欧美日韩系列| 99pao成人国产永久免费视频| 亚洲在线视频免费观看| 这里只有精品视频| 午夜综合激情| 亚洲在线国产日韩欧美| 新67194成人永久网站| 久久精品日韩| 亚洲国产91精品在线观看| 亚洲激情在线观看| 亚洲视频福利| 久久不射2019中文字幕| 亚洲一区bb| 久久精品99国产精品日本| 麻豆乱码国产一区二区三区| 欧美劲爆第一页| 国产精一区二区三区| 狠狠色丁香婷综合久久| 亚洲三级色网| 久久福利电影| 亚洲精品一区在线观看| 日韩天天综合| 欧美gay视频| 亚洲视频福利| 免费在线观看精品| 国产乱码精品1区2区3区| 亚洲电影免费观看高清| 亚洲国产mv| 久久精品视频99| 99精品欧美一区| 久久久久久欧美| 国产精品九九久久久久久久| 在线观看一区欧美| 亚洲精品视频在线| 久久香蕉国产线看观看网| 亚洲精品小视频| 老司机67194精品线观看| 国产美女一区二区| 这里只有精品在线播放| 销魂美女一区二区三区视频在线| 欧美激情欧美狂野欧美精品| 午夜国产一区| 欧美性视频网站| 亚洲美女av在线播放| 久久视频国产精品免费视频在线 | 国产精品欧美日韩一区二区| 午夜精品久久久久久久| 欧美18av| 在线免费观看成人网| 西瓜成人精品人成网站| 欧美激情成人在线| 久久蜜桃香蕉精品一区二区三区| 国产精品综合网站| 性做久久久久久久久| 在线亚洲欧美| 欧美色图天堂网| 在线视频精品| 亚洲欧洲在线一区| 欧美电影电视剧在线观看| 亚洲国产精品久久久久婷婷884| 亚洲精选视频免费看| 亚洲激情av| 欧美精品在线观看| 在线中文字幕日韩| 日韩午夜在线播放| 模特精品裸拍一区| 亚洲精品影视| 亚洲精品国久久99热| 欧美日韩国产在线播放| 国产一区二区无遮挡| 久久激情综合| 久久九九国产精品| 亚洲福利国产| 亚洲精品久久| 国产精品日韩一区二区三区| 欧美一级视频精品观看| 日韩一本二本av| 国产精品扒开腿做爽爽爽软件| 国产精品99久久久久久有的能看| 一区二区三区四区五区精品视频| 免费观看一区| 亚洲一区二区欧美日韩| 一本到12不卡视频在线dvd| 久久国产夜色精品鲁鲁99| 最新国产の精品合集bt伙计| 欧美精品一区二区三区高清aⅴ| 亚洲视频一区二区| 久久国产毛片| 亚洲影视在线| 久久伊人亚洲| 亚洲欧美电影在线观看| 久久久久国产成人精品亚洲午夜| 日韩视频永久免费观看| 久久国产精品99国产精| 亚洲自拍偷拍麻豆| 欧美激情一区| 欧美插天视频在线播放| 国产精品一区免费视频| 亚洲精品日本| 亚洲欧洲日本国产| 欧美在线观看网址综合| 中文在线资源观看网站视频免费不卡 | 国产亚洲一区二区三区在线观看 | 亚洲精品123区| 国产欧美日韩不卡| 99视频国产精品免费观看| 欲色影视综合吧| 欧美一区影院| 欧美中文字幕不卡| 国产精品美女在线观看| 日韩亚洲一区二区| 一本久久青青| 欧美日韩精品伦理作品在线免费观看| 美日韩丰满少妇在线观看| 国产日韩欧美在线观看| 午夜欧美精品久久久久久久| 午夜电影亚洲| 国产视频一区欧美| 欧美一区二区三区精品| 久久精品国产99| 狠狠色丁香久久婷婷综合_中| 欧美一区二区精品久久911| 久久激情中文| 国内一区二区在线视频观看| 久久成人精品视频| 免费h精品视频在线播放| 在线观看日韩专区| 蜜桃久久av| 99视频国产精品免费观看| 亚洲一级黄色| 国产日韩欧美在线| 久久免费国产精品| 亚洲精品1区2区| 亚洲一区三区视频在线观看| 国产精品婷婷| 久久久久亚洲综合| 亚洲国产精品va| 亚洲在线成人| 国产一区二三区| 嫩草国产精品入口| 99riav1国产精品视频| 欧美一区二区视频在线| 尤物yw午夜国产精品视频| 久久综合亚州| 中文精品一区二区三区| 欧美亚洲免费| 亚洲国产精品电影在线观看| 欧美日韩黄色大片| 久久精品国产久精国产爱| 亚洲高清不卡在线| 亚洲一区综合| 在线看一区二区| 国产精品久久久久aaaa| 久久精品二区三区| 亚洲精品在线观看免费| 久久精品91久久香蕉加勒比| 亚洲人体偷拍| 国产欧美亚洲一区| 欧美剧在线免费观看网站| 欧美一区二区视频在线观看2020| 亚洲国产综合91精品麻豆| 欧美在线视频一区二区| 日韩视频在线播放| 狠狠色狠狠色综合| 欧美午夜不卡在线观看免费| 久久国产精品99国产精| 一区二区日韩免费看| 欧美承认网站| 久久精品二区亚洲w码| 欧美一区二区三区婷婷月色| 国产欧美日韩中文字幕在线| 欧美电影免费观看高清| 亚洲欧美精品| 一区二区日韩| 亚洲全部视频| 欧美91大片| 久久精精品视频| 亚洲天堂网在线观看| 亚洲激情在线观看| 韩国精品在线观看| 国产手机视频精品| 国产精品久久久久毛片大屁完整版 |