一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

函數(shù)調(diào)用約定

 TUBOSS 2014-09-30

函數(shù)調(diào)用約定包括傳遞參數(shù)的順序,誰負責清理參數(shù)占用的堆棧等,例如 :

  參數(shù)傳遞順序 誰負責清理參數(shù)占用的堆棧
__pascal 從左到右 調(diào)用者
__stdcall 從右到左 被調(diào)函數(shù)
__cdecl 從右到左 調(diào)用者

調(diào)用函數(shù)的代碼和被調(diào)函數(shù)必須采用相同的函數(shù)的調(diào)用約定,程序才能正常運行。在Windows上,__cdecl是C/C++程序的缺省函數(shù)調(diào)用約定。

在有的cpu上,編譯器會用寄存器傳遞參數(shù),函數(shù)使用的堆棧由被調(diào)函數(shù)分配和釋放。這種調(diào)用約定在行為上和__cdecl有一個共同點:實參和形參數(shù)目不符不會導致堆棧錯誤。

不過,即使用寄存器傳遞參數(shù),編譯器在進入函數(shù)時,還是會將寄存器里的參數(shù)存入堆棧指定位置。參數(shù)和局部變量一樣應該在堆棧中有一席之地。參數(shù)可以被理解為由調(diào)用函數(shù)指定初值的局部變量。

_stdcall與_cdecl的不同

a. 默認支持:VC默認使用_cdecl。所以如果需要使用_stdcall,可采用兩種方法:(1)可以在函數(shù)名前手工添加,只對單一函數(shù)有效 (2)直接修改工程屬性(C/C++ > Advanced > Calling Convention)來一次性配置所有的函數(shù)

b. 功能不同: _cdecl可實現(xiàn)變長參數(shù)列表

c. 代碼大?。篲stdcall更小

d. 速度不同: _cdecl更快(代碼更多當然意味著運行更快,有點像內(nèi)聯(lián)函數(shù))

e. 誰負責恢復堆棧:_cdecl主調(diào)用函數(shù)進行參數(shù)壓棧并且恢復堆棧;_stdcall主調(diào)用函數(shù)進行參數(shù)壓棧,被調(diào)函數(shù)恢復堆棧;這也正是產(chǎn)生
   a). 不同代碼大小的原因:如果使用_cdecl的函數(shù)多次調(diào)用同一函數(shù),就要產(chǎn)生多份恢復碼。
   b). 功能不同的原因:實現(xiàn)變長參數(shù)列表。一份恢復碼只能將一種長度的參數(shù)表出棧,所以要對不同長度的參數(shù)表堆棧恢復,必須要有多份代碼,所以變長參數(shù)必須有主調(diào)函數(shù)恢復(所以是_cdecl)。

f. 產(chǎn)生的函數(shù)名不同:

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

g. 使用范圍:

_stdcall:通常用于DLL的創(chuàng)建(以支持多語言調(diào)用);此外Win32 API函數(shù)皆用_stdcall(比如MessageBox),所以Win32程序中的自定義函數(shù)也做好使用_stdcall。
_cdecl:非DLL的console程序。

 

跨語言調(diào)用
函數(shù)調(diào)用約定只是“調(diào)用函數(shù)的代碼”和被調(diào)用函數(shù)之間的關系。

假設函數(shù)A是__stdcall,函數(shù)B調(diào)用函數(shù)A。你必須通過函數(shù)聲明告訴編譯器,函數(shù)A是__stdcall。編譯器自然會產(chǎn)生正確的調(diào)用代碼。

如果函數(shù)A是__stdcall。但在引用函數(shù)A的地方,你卻告訴編譯器,函數(shù)A是__cdecl方式,編譯器產(chǎn)生__cdecl方式的代碼,與函數(shù)A的調(diào)用約定不一致,就會發(fā)生錯誤。

以delphi調(diào)用VC函數(shù)為例,delphi的函數(shù)缺省采用__pascal約定,VC的函數(shù)缺省采用__cdecl約定。我們一般將VC的函數(shù)設為__stdcall,例如:

int __stdcall add(int a, int b);

在delphi中將這個函數(shù)也聲明為__stdcall,就可以調(diào)用了:

function add(a: Integer; b: Integer): Integer;
stdcall; external ‘a(chǎn).dll’;

因為考慮到可能被其它語言的程序調(diào)用,不少API采用__stdcall的調(diào)用約定。

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    久久机热频这里只精品| 日韩人妻中文字幕精品| 亚洲专区中文字幕视频| 国产肥妇一区二区熟女精品| 国产成人精品一区二区在线看| 精品推荐国产麻豆剧传媒| 成人日韩视频中文字幕| 不卡中文字幕在线免费看| 日本淫片一区二区三区| 九九热精品视频在线观看| 国产精品偷拍一区二区| 亚洲国产av国产av| 久久国产亚洲精品成人| 欧美大粗爽一区二区三区| 国产午夜福利片在线观看| 99久只有精品免费视频播放| 精品日韩中文字幕视频在线| 正在播放国产又粗又长| 内射精子视频欧美一区二区| 白丝美女被插入视频在线观看| 久久中文字人妻熟女小妇| 国产日韩欧美国产欧美日韩| 亚洲精品国产福利在线| 日本 一区二区 在线| 91在线爽的少妇嗷嗷叫| 精品人妻一区二区三区四区久久| 国产精品视频第一第二区| 日韩1区二区三区麻豆| 欧美一区二区三区99| 日韩一区二区三区久久| 国产成人综合亚洲欧美日韩| 老外那个很粗大做起来很爽| 欧美亚洲91在线视频| 99久久国产精品亚洲| 日韩专区欧美中文字幕| 青青操精品视频在线观看| 欧美亚洲91在线视频| 免费观看日韩一级黄色大片| 日韩亚洲精品国产第二页| 女厕偷窥一区二区三区在线| 内射精品欧美一区二区三区久久久|