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

posts - 297,  comments - 15,  trackbacks - 0

(VC編譯器下)

 

1. CALLBACKWINAPIAFXAPI到底是什么?它們分別在什么地方 被定義的?

在頭文件windef.h中,CALLBACK, WINAPI, APIENTRY

……

#define CALLBACK  __stdcall

#define WINAPI         __stdcall

#define WINAPIV       __cdecl

#define APIENTRY    WINAPI

……

 

在頭文件AFXVER_.H中,AFXAPI的定義如下:

    ……

   // AFXAPI is used on global public functions

#ifndef AFXAPI

        #define AFXAPI __stdcall

#endif

    ……

 

2. __stdcall__cdecl有什么作用?他們的區(qū)別是什么?

a. __stdcall是新標(biāo)準(zhǔn)C/C++函數(shù)的調(diào)用方法。從底層上說(shuō),使用這種調(diào)用方法參數(shù)的進(jìn)棧順序和 標(biāo)準(zhǔn)C調(diào)用(__cdecl方法)是一樣的,都

  是從右到左,但是__stdcall采用自動(dòng)清棧的方式,而__cdecl是手工清棧。

b. windows規(guī)定,凡事由它來(lái)負(fù)責(zé)調(diào)用的函數(shù)必須定義為_stdcall類型,比如回調(diào)函數(shù)、WinMain函數(shù)等。

c. 如果沒(méi)有顯試聲明的話,函數(shù)的調(diào)用方法默認(rèn)是__cdecl。

 

3. 調(diào)用約定種類

   一共有5中函數(shù)調(diào)用約定(calling convention),它決定一下內(nèi) 容:

   1) 函數(shù)參數(shù)的壓棧順序

   2) 由調(diào)用者還是被調(diào)用者把參數(shù)彈出棧

   3) 產(chǎn)生函數(shù)修飾名的方法

 

__stdcall調(diào)用約定:

函數(shù)的參數(shù)自右向左通過(guò)棧傳遞,被調(diào)用的函數(shù)在返回前清理傳送參數(shù)的內(nèi)存棧,

 

__cdecl調(diào)用約定:

是C和C++程序的缺省調(diào)用方式。每一個(gè)調(diào)用它的函數(shù)都包含清空堆棧的代碼, 所以產(chǎn)生的可執(zhí)行文件大小會(huì)比調(diào)用__stdcall函數(shù)的大。函數(shù)采用從右到左的壓棧方式。注意:對(duì)于可變參數(shù)的成員函數(shù),始終使用__cdecl的轉(zhuǎn)換方式。

 

__fastcall調(diào)用約定:

它是通過(guò)寄存器來(lái)傳送參數(shù)的(實(shí)際上,它用ECX和EDX傳送前兩個(gè)雙字(DWORD)或更小的參數(shù),剩下的參數(shù)仍舊自右向左壓棧傳送,被調(diào)用的函數(shù)在 返回前清理傳送參數(shù)的內(nèi)存棧)。

 

thiscall調(diào)用約定:

僅僅應(yīng)用于"C++"成 員函數(shù)。this指 針存放于CX寄存 器,參數(shù)從右到左壓。thiscall不是關(guān)鍵詞,因此不能被程序員指定。

 

naked call調(diào)用約定:

采用上述4種調(diào)用約 定時(shí),如果必要的話,進(jìn)入函數(shù)時(shí)編譯器會(huì)產(chǎn)生代碼來(lái)保存ESI,EDI,EBX,EBP寄存器,退出函數(shù)時(shí)則產(chǎn)生代碼恢復(fù)這些寄存器的內(nèi)容。naked call不產(chǎn)生這樣的代碼。naked call不是類型修飾符,故必須和_declspec共同使用。

 

關(guān)鍵字 __stdcall、__cdecl 和 __fastcall 可以直接加在要輸出的函數(shù)前,也可以在編譯環(huán)境的 Setting...\C/C++ \Code Generation 項(xiàng)選擇。當(dāng)加在 輸出函數(shù)前的關(guān)鍵字與編譯環(huán)境中的選擇不同時(shí),直接加在輸出函數(shù)前的關(guān)鍵字有效。它們對(duì)應(yīng)的命令行參數(shù)分別為/Gz、/Gd 和 /Gr。缺省狀態(tài)為/Gd,即__cdecl。缺省狀態(tài)為__cdecl。

 

4. 名 字修飾約定

"C" 或者 "C++" 函數(shù)在內(nèi)部(編譯和鏈接)通過(guò)修飾名識(shí)別。修飾名是編譯器在編譯 函數(shù)定義或者原型時(shí)生成的字符串。有些情況下使用函數(shù)的修飾名是必要的,如在模塊定義文件里頭指定輸出"C++"重載函數(shù)、構(gòu)造函數(shù)、析構(gòu)函數(shù),又如在匯編代碼里調(diào)用"C""或"C++"函數(shù)等。修飾名由函數(shù)名、類名、調(diào)用約定、返回類型、參數(shù)等共同 決定。函數(shù)名修飾約定隨編譯種類(C或C++)和調(diào)用約定的不同而不同,下面分別說(shuō)明。

 

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ù)名中的字符大小寫。

 

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

__stdcall調(diào)用約定:

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

參數(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ù);

 

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

參數(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”(第一個(gè)X表示返回類型,第二個(gè)X表示參數(shù) 類型)

 

__cdecl調(diào)用約定:

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

 

__fastcall調(diào)用約定:

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

 

對(duì)于C++的類成員函數(shù)(其調(diào)用方式是thiscall),函數(shù)的名字修飾與非成員的C++函數(shù)稍有不同,首先就是在函數(shù)名字和參數(shù)表之間插入以“@”字符引導(dǎo)的類名;其次是參數(shù)表的開始標(biāo)識(shí)不同,公有(public)成員函數(shù)的標(biāo)識(shí)是“@@QAE”,保護(hù)(protected)成員函數(shù)的標(biāo)識(shí)是“@@IAE”,私有(private)成員函數(shù)的標(biāo)識(shí)是“@@AAE”,如果函數(shù)聲明使用了const關(guān)鍵字,則相應(yīng)的標(biāo)識(shí)應(yīng)分別為“@@QBE”,“@@IBE”和“@@ABE”。如果參數(shù)類型是類實(shí)例的引用,則使用“AAV1”,對(duì)于const類型的引用,則使用“ABV1”。下面就以類CTest為例說(shuō)明C++成員函數(shù)的名字修飾規(guī)則:

class CTest

{

......

private:

    void Function(int);

protected:

    void CopyInfo(const CTest &src);

public:

    long DrawText(HDC hdc, long pos, const TCHAR* text, RGBQUAD color, BYTE bUnder, bool bSet);

    long InsightClass(DWORD dwClass) const;

......

};

對(duì)于成員函數(shù)Function,其函數(shù)修飾名為“?Function@CTest@@AAEXH@Z”,字符串“@@AAE”表示這是一個(gè)私有函數(shù)。“X”表示返回類型為void,“H”表示參數(shù)類型為int類型。

 

成員函數(shù)CopyInfo只有一個(gè)參數(shù),是對(duì)類CTest的const引用參數(shù),其函數(shù)修飾名為“?CopyInfo@CTest@@IAEXABV1@@Z”。

 

DrawText是一個(gè)比較復(fù)雜的函數(shù)聲明,不僅有字符串參數(shù),還有結(jié)構(gòu)體參數(shù)和HDC句柄參數(shù),需要指出的是HDC實(shí)際上是一個(gè)HDC__結(jié)構(gòu)類型的指針,這個(gè)參數(shù)的表示就是“PAUHDC__@@”,其完整的函數(shù)修飾名為“?DrawText@CTest@@QAEJPAUHDC__@@JPBDUtagRGBQUAD@@E_N@Z”。

 

InsightClass是一個(gè)共有的const函數(shù),它的成員函數(shù)標(biāo)識(shí)是“@@QBE”,完整的修飾名就是“?InsightClass@CTest@@QBEJK@Z”。

 

舉例:

比如動(dòng)態(tài)鏈接庫(kù)a有以下導(dǎo)出函數(shù):

long MakeFun(long lFun);

動(dòng)態(tài)庫(kù)生成的時(shí)候采用的函數(shù)調(diào)用約定是__stdcall,所以編譯生成的a.dll中函數(shù)MakeFun的調(diào)用約定是_stdcall,也就是函數(shù)調(diào)用時(shí)參數(shù)從右向左入棧,函數(shù)返回時(shí)自己還原堆棧。現(xiàn)在某個(gè)程序模塊b要引用a中的MakeFun,b和a一樣使用C++方式編譯,只是b模塊的函數(shù)調(diào)用方式是__cdecl,由于b包含了a提供的頭文件中MakeFun函數(shù)聲明,所以MakeFun在b模塊中被 其它調(diào)用MakeFun的函數(shù)認(rèn)為是__cdecl調(diào)用方式,b模塊中的 這些函數(shù)在調(diào)用完MakeFun當(dāng)然要幫著恢復(fù)堆棧啦,可是MakeFun已經(jīng)在結(jié)束時(shí)自己恢復(fù)了堆棧,b模塊中的函數(shù)這樣多此一舉就引起了棧指針錯(cuò)誤,從而引發(fā)堆棧異常。宏觀上的現(xiàn)象就是函數(shù)調(diào)用沒(méi)有問(wèn)題(因?yàn)閰?shù)傳遞 順序是一樣的),MakeFun也完成了自己的功能,只是函數(shù)返回后引發(fā)錯(cuò)誤。解決的方法也很簡(jiǎn)單,只要保證兩個(gè)模塊的在編譯時(shí)設(shè)置相同的函數(shù)調(diào)用約定就行了。

 

現(xiàn)在再假定兩個(gè)模塊在編譯的時(shí)候都采用__stdcall調(diào)用約定,但是a.dll使用C語(yǔ)言的語(yǔ)法編譯的(C語(yǔ)言方式),所以a.dll的 載入庫(kù)a.lib中MakeFun函數(shù)的名字修飾就是“_MakeFun@4”。b包含了a提供的頭文件中MakeFun函數(shù)聲明,但是由于b采用的是C++語(yǔ)言編譯,所以MakeFun在b模塊中被按照C++的名字修飾規(guī)則命名為“?MakeFun@@YGJJ@Z”,編譯過(guò)程相安無(wú)事,鏈接程序時(shí)c++的鏈接器就到a.lib中去找“?MakeFun@@YGJJ@Z”,但是a.lib中只有“_MakeFun@4”,沒(méi)有“?MakeFun@@YGJJ@Z”,于是鏈接器就報(bào)告:

error LNK2001: unresolved external symbol ?MakeFun@@YGJJ@Z

解決的方法和簡(jiǎn)單,就是要讓b模塊知道這個(gè)函數(shù)是C語(yǔ)言編譯的,extern "C"可以做到這一點(diǎn)。一個(gè)采用C語(yǔ)言編譯的庫(kù)應(yīng)該考慮到使用這個(gè)庫(kù)的程序可能是C++程序(使用C++編譯器),所以在設(shè)計(jì)頭文件時(shí)應(yīng)該注意這一點(diǎn)。通常應(yīng)該這樣聲明 頭文件:

#ifdef _cplusplus

extern "C" {

#endif

long MakeFun(long lFun);

#ifdef _cplusplus

}

#endif

這樣C++的編譯器就知道MakeFun的修飾名是“_MakeFun@4”,就不會(huì)有鏈接錯(cuò)誤了。

 

許多人不明白,為什么我使用的編譯器都是VC的編譯器還會(huì)產(chǎn)生“error LNK2001”錯(cuò)誤?其實(shí),VC的編譯器會(huì)根據(jù)源文件的擴(kuò)展名選擇編譯方式,如果文件的擴(kuò)展名是“.C”,編譯器會(huì)采用C的語(yǔ)法編譯,如果擴(kuò)展名是“.cpp”,編譯器會(huì)使用C++的語(yǔ)法編譯程序,所以,最好的方法就是使用extern "C"。

 

5. 單看函數(shù)的名字修飾

有兩種方式可以檢查你的程序中的函數(shù)的名字修飾:使用編譯輸出列表或使用Dumpbin工具。使用/FAc,/FAs或/FAcs命令行參數(shù)可以讓編譯器輸出函數(shù)或變量名字列表。使用dumpbin.exe /SYMBOLS命令也可以獲得obj文件或lib文件中的函數(shù)或變量名字列表。此外,還可以使用 undname.exe 將修飾名轉(zhuǎn)換為未修飾形式。

from:
http://patmusing.blog.163.com/blog/static/13583496020103233446784/

posted on 2010-04-28 00:10 chatler 閱讀(622) 評(píng)論(0)  編輯 收藏 引用 所屬分類: windows
<2025年9月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

常用鏈接

留言簿(10)

隨筆分類(307)

隨筆檔案(297)

algorithm

Books_Free_Online

C++

database

Linux

Linux shell

linux socket

misce

  • cloudward
  • 感覺(jué)這個(gè)博客還是不錯(cuò),雖然做的東西和我不大相關(guān),覺(jué)得看看還是有好處的

network

OSS

  • Google Android
  • Android is a software stack for mobile devices that includes an operating system, middleware and key applications. This early look at the Android SDK provides the tools and APIs necessary to begin developing applications on the Android platform using the Java programming language.
  • os161 file list

overall

搜索

  •  

最新評(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>
            亚洲欧美另类国产| 亚洲欧美日韩区| 亚洲一区二三| 国产美女扒开尿口久久久| 亚洲大胆美女视频| 亚洲二区免费| 欧美体内she精视频在线观看| 一本色道久久综合| 亚洲网友自拍| 激情五月综合色婷婷一区二区| 美女黄毛**国产精品啪啪| 美日韩在线观看| 亚洲一区在线播放| 久久精彩视频| 一区二区三区视频在线 | 亚洲国产精品成人精品| 亚洲大胆女人| 国产精品国产馆在线真实露脸| 欧美专区一区二区三区| 久久午夜av| 亚洲国产视频直播| 欧美裸体一区二区三区| 日韩一级网站| 欧美日韩在线观看视频| 国产精品一区二区三区四区| 久久久www免费人成黑人精品| 久久人人97超碰国产公开结果| 亚洲精品偷拍| 欧美一区二区三区免费看| 亚洲精品三级| 久久精品毛片| 欧美一区二区三区免费看| 欧美aⅴ99久久黑人专区| 亚洲在线播放电影| 欧美va天堂| 久久亚洲春色中文字幕久久久| 欧美日韩免费高清| 欧美福利电影网| 国产自产2019最新不卡| 香蕉成人久久| 国产精品久久久久aaaa| 欧美在线视频在线播放完整版免费观看 | 亚洲欧洲日韩综合二区| 国产日产高清欧美一区二区三区| 亚洲欧洲三级| 欧美激情二区三区| 一区免费在线| 午夜精品久久久久久久99樱桃| 亚洲精品日韩欧美| 久久综合色88| 免费欧美高清视频| 黑人极品videos精品欧美裸| 亚洲免费小视频| 亚洲免费在线视频一区 二区| 欧美极品一区| 亚洲黄色有码视频| 亚洲精品国精品久久99热| 久久男人av资源网站| 久久综合久久88| 在线观看日韩| 久久人人97超碰国产公开结果| 久久久午夜电影| 狠狠色丁香久久婷婷综合_中| 午夜精品久久久| 久久精品免费| 悠悠资源网久久精品| 久久九九精品| 欧美激情影音先锋| 日韩视频国产视频| 欧美日韩在线视频首页| 亚洲视频在线二区| 欧美一区二区三区免费视| 国产日韩一级二级三级| 欧美有码在线视频| 欧美国产亚洲另类动漫| 亚洲人成高清| 国产精品第十页| 午夜亚洲激情| 欧美r片在线| 夜夜嗨av一区二区三区网站四季av| 欧美激情91| 亚洲一区二区在线播放| 久久久噜噜噜久久| 亚洲黄色影片| 国产精品家庭影院| 欧美在线播放视频| 91久久精品美女| 欧美在线999| 亚洲国产精品久久久| 欧美日韩亚洲一区二区| 欧美在线亚洲在线| 模特精品在线| 中文av字幕一区| 国产一区二区三区直播精品电影| 久久久亚洲影院你懂的| 亚洲精品免费网站| 久久久久久久久久码影片| 亚洲欧洲另类| 国产欧美日韩精品丝袜高跟鞋| 老司机成人网| 亚洲男人的天堂在线观看| 欧美成人69| 午夜免费久久久久| 亚洲电影成人| 国产模特精品视频久久久久| 美女成人午夜| 欧美亚洲综合另类| 亚洲国产专区校园欧美| 久久精品国产亚洲a| 一区二区三区产品免费精品久久75| 国产精品久久久一区二区| 欧美超级免费视 在线| 欧美一进一出视频| 夜色激情一区二区| 亚洲国产精品高清久久久| 久久久久国产精品一区| 亚洲一区二区在线观看视频| 欧美经典一区二区| 欧美a级片一区| 久久av老司机精品网站导航| 亚洲日韩欧美一区二区在线| 国产午夜亚洲精品理论片色戒| 欧美人成网站| 欧美国产日产韩国视频| 久久精品国产欧美亚洲人人爽| 亚洲专区在线视频| 99精品国产一区二区青青牛奶 | 亚洲片区在线| 精品999网站| 国产在线观看91精品一区| 国产精品日韩在线观看| 欧美性猛交视频| 欧美体内she精视频| 欧美日本簧片| 欧美视频一区二区三区| 欧美精品免费观看二区| 欧美成人一二三| 免费观看亚洲视频大全| 美女久久网站| 欧美成人激情在线| 欧美激情一区在线| 欧美伦理影院| 国产精品高潮呻吟久久av无限| 欧美日韩一卡二卡| 欧美午夜激情小视频| 国产精品拍天天在线| 国产精品视频一区二区三区| 国产精品免费一区二区三区在线观看 | 国产一区二区三区在线播放免费观看 | 裸体素人女欧美日韩| 能在线观看的日韩av| 欧美国产精品劲爆| 欧美日韩在线视频首页| 国产精品免费观看在线| 国产伦精品一区| 狠狠狠色丁香婷婷综合激情| 在线看片成人| 在线视频亚洲一区| 欧美一区二区三区啪啪| 久久深夜福利免费观看| 免费亚洲一区| 99精品欧美一区二区三区| 亚洲免费视频观看| 麻豆国产精品va在线观看不卡| 欧美日韩国产一区精品一区| 国产精品美女久久久| 韩国一区二区三区美女美女秀| 亚洲日韩欧美视频| 欧美亚洲综合久久| 欧美不卡高清| 亚洲一区二区三区777| 久久久久久欧美| 欧美精品二区三区四区免费看视频| 欧美性jizz18性欧美| 狠狠色狠狠色综合系列| 在线亚洲高清视频| 狂野欧美激情性xxxx欧美| 亚洲精品视频啊美女在线直播| 午夜国产精品视频| 欧美成人日本| 国产偷自视频区视频一区二区| 日韩午夜av电影| 久久九九全国免费精品观看| 亚洲激情黄色| 久久青青草原一区二区| 国产精品久久久久免费a∨| 亚洲激情一区| 久久久久久亚洲精品杨幂换脸 | 亚洲精品免费一区二区三区| 久久男女视频| 亚洲高清免费在线| 亚洲欧美文学| 欧美日韩国产精品一卡| 激情综合久久| 久久成年人视频| 亚洲一区二区三区免费视频| 欧美/亚洲一区| 一区视频在线播放| 久久精品99久久香蕉国产色戒| 日韩一区二区精品|