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

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>
            夜夜嗨av一区二区三区网站四季av| 亚洲午夜一区二区三区| 亚欧成人在线| 久久夜色精品国产欧美乱| 99热这里只有精品8| 亚洲成人在线视频播放 | 国内视频精品| 国产亚洲一区在线| 国产一区二区三区在线观看精品 | 久久成年人视频| 欧美诱惑福利视频| 免费视频一区| 你懂的视频一区二区| 欧美激情在线观看| 国产精品久久久久久久久婷婷| 国产精品日日摸夜夜添夜夜av| 国产亚洲一区二区三区| 亚洲国产欧美一区| 在线亚洲一区二区| 久久av在线| 欧美黑人在线播放| 一区二区三区高清在线观看| 欧美一区二区视频在线| 欧美 亚欧 日韩视频在线| 国产精品国产三级国产aⅴ入口 | 一区二区三区黄色| 久久国内精品视频| 亚洲第一黄网| 亚洲免费一级电影| 欧美国产日韩精品| 国产一区在线播放| 一本色道久久综合亚洲91| 久久九九99| 夜夜爽99久久国产综合精品女不卡| 欧美影院成人| 欧美丝袜第一区| 亚洲欧美日韩综合| 欧美成人黑人xx视频免费观看| 国产精品久久777777毛茸茸| 亚洲高清免费在线| 久久99在线观看| 中日韩男男gay无套| 欧美成人官网二区| 精品粉嫩aⅴ一区二区三区四区| 亚洲午夜久久久久久久久电影网| 噜噜噜久久亚洲精品国产品小说| 亚洲自拍都市欧美小说| 欧美日本在线播放| 亚洲精品视频在线观看免费| 另类图片综合电影| 久久精品盗摄| 国产精品免费aⅴ片在线观看| 亚洲精品美女久久7777777| 久久久久久穴| 午夜国产精品视频| 国产精品久久久久久久午夜| 中文国产一区| 亚洲国产精选| 在线视频一区二区| 欧美精品福利视频| 国产欧美一区二区三区在线老狼| 欧美成ee人免费视频| 亚洲综合色丁香婷婷六月图片| 欧美日本一道本在线视频| 亚洲电影免费在线观看| 老司机aⅴ在线精品导航| 午夜精品亚洲| 国产在线精品一区二区中文| 久久激情综合网| 欧美一区二区三区免费看| 国产欧美日韩在线视频| 久久精品网址| 久久综合九色综合欧美就去吻| 今天的高清视频免费播放成人 | 亚洲高清视频在线观看| 免费成人av资源网| 亚洲精品影院在线观看| 亚洲人体一区| 欧美特黄一级大片| 欧美综合国产| 欧美成人午夜免费视在线看片| 亚洲精品国产无天堂网2021| 亚洲国产裸拍裸体视频在线观看乱了中文| 欧美.日韩.国产.一区.二区| 国产精品99久久久久久有的能看 | 99re6热在线精品视频播放速度| 欧美日韩一区不卡| 性感少妇一区| 久久精品99国产精品日本| 亚洲国产美女精品久久久久∴| 最新国产乱人伦偷精品免费网站 | 欧美午夜在线视频| 久久精品国产精品亚洲精品| 久久亚洲一区| 亚洲一级片在线看| 久久久人成影片一区二区三区| 日韩网站在线看片你懂的| 亚洲图片欧洲图片av| 好看的亚洲午夜视频在线| 亚洲国产综合视频在线观看| 国产精品久久亚洲7777| 欧美阿v一级看视频| 国产精品久久久久久久久久免费看| 久久久久久有精品国产| 欧美日韩亚洲国产一区| 久久综合久久综合九色| 欧美日韩亚洲激情| 欧美电影在线播放| 国产欧美一区二区三区久久| 亚洲国产一区二区三区a毛片| 国产精品亚洲产品| 亚洲精品美女91| 伊人色综合久久天天| 亚洲一区二区精品| 欧美四级电影网站| 榴莲视频成人在线观看| 国产精品午夜春色av| 狠狠色综合网站久久久久久久| 欧美在线日韩精品| 免费中文字幕日韩欧美| 亚洲欧美日韩国产另类专区| 久久久蜜桃精品| 欧美一区综合| 欧美日韩国产精品| 亚洲成人直播| **欧美日韩vr在线| 久久www成人_看片免费不卡| 亚洲一级一区| 欧美日韩一区二区在线播放| 欧美大片免费观看在线观看网站推荐| 国产精品视频精品视频| 99在线精品观看| 正在播放亚洲一区| 欧美激情按摩| 91久久精品美女| 亚洲人成网站影音先锋播放| 免费在线成人av| 亚洲高清视频一区| 亚洲免费高清| 欧美精品在线看| 亚洲国产欧美日韩另类综合| 亚洲电影免费| 久久久美女艺术照精彩视频福利播放 | 蜜桃av综合| 欧美电影在线免费观看网站| 亚洲第一狼人社区| 欧美bbbxxxxx| 亚洲精品老司机| 亚洲性视频网站| 国产精品稀缺呦系列在线| 亚洲在线观看免费| 久久久久久夜| 亚洲国产欧美一区二区三区丁香婷| 久久午夜视频| 91久久午夜| 午夜精品视频在线| 国产亚洲精品自拍| 美女脱光内衣内裤视频久久影院| 亚洲福利电影| 亚洲女ⅴideoshd黑人| 国产欧美精品在线观看| 久久久久国产免费免费| 亚洲精品美女久久7777777| 香蕉亚洲视频| 亚洲第一在线视频| 欧美色图首页| 久久成人国产| 亚洲人永久免费| 小黄鸭精品aⅴ导航网站入口| 国产伊人精品| 欧美激情中文字幕乱码免费| 亚洲在线观看视频网站| 久久伊人亚洲| 在线视频你懂得一区| 国产欧美日韩亚洲精品| 欧美成人69| 先锋影音一区二区三区| 亚洲大胆在线| 久久av二区| 亚洲视频综合在线| 亚洲成在线观看| 国产伦精品一区二区三区免费迷 | 亚洲日本激情| 国产精品护士白丝一区av| 久久精品五月| 在线亚洲自拍| 亚洲国产日韩综合一区| 欧美有码在线观看视频| 9色精品在线| 亚洲高清不卡在线观看| 国产精品一区二区三区久久| 久久伊人免费视频| 亚洲一区二区三区精品动漫| 亚洲电影av在线| 久久免费精品日本久久中文字幕| 99精品国产福利在线观看免费 | 欧美搞黄网站| 久久久久久69| 午夜精品久久久久久久蜜桃app| 亚洲国产精品毛片|