程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> C/C++函數挪用的幾種方法總結

C/C++函數挪用的幾種方法總結

編輯:關於C++

C/C++函數挪用的幾種方法總結。本站提示廣大學習愛好者:(C/C++函數挪用的幾種方法總結)文章只能為提供參考,不一定能成為您想要的結果。以下是C/C++函數挪用的幾種方法總結正文


挪用函數時,盤算機經常使用棧來存儲傳遞給函數的參數。

棧是一種先輩後出的數據構造,棧有一個存儲區、一個棧頂指針。棧頂指針指向客棧中第一個可用的數據項(被稱為棧頂)。用戶可以在棧頂上偏向棧中參加數據,這個操作被稱為壓棧(Push),壓棧今後,棧頂主動釀成新參加數據項的地位,棧頂指針也隨之修正。用戶也能夠從客棧中取走棧頂,稱為彈出棧(pop),彈出棧後,棧頂下的一個元素釀成棧頂,棧頂指針隨之修正。函數挪用時,挪用者順次把參數壓棧,然後挪用函數,函數被挪用今後,在客棧中獲得數據,並停止盤算。函數盤算停止今後,或許挪用者、或許函數自己修正客棧,使客棧恢回復復興裝。

在參數傳遞中,有兩個主要的成績必需要明白解釋:

1. 當參數個數多於一個時,依照甚麼次序把參數壓入客棧;

2. 函數挪用後,由誰來把客棧恢回復復興狀。


在高等說話中,就是經由過程函數的挪用方法來講明這兩個成績的。罕見的挪用方法有:

stdcall

cdecl

fastcall

thiscall

thiscall

naked call


上面就分離引見這幾種挪用方法:
 

1. stdcall

stdcall挪用方法又被稱為Pascal挪用方法。在Microsoft C++系列的C/C++編譯器中,應用PASCAL宏,WINAPI宏和CALLBACK宏來指定函數的挪用方法為stdcall。

stdcall挪用方法的函數聲明為:

int _stdcall function(int a, int b);

stdcall的挪用方法意味著:

(1) 參數從右向左一次壓入客棧

(2) 由被挪用函數本身來恢復客棧

(3) 函數名主動加前導下劃線,前面緊隨著一個@,厥後緊隨著參數的尺寸

下面誰人函數翻譯成匯編說話將釀成:

push b     先壓入第二個參數

push a     再壓入第一個參數

call function   挪用函數


在編譯時,此函數的名字被翻譯為_function@8


2. cdecl

cdecl挪用方法又稱為C挪用方法,是C說話缺省的挪用方法,它的語法為:

int function(int a, int b)  // 不加潤飾符就是C挪用方法

int _cdecl function(int a, int b)  // 明白指定用C挪用方法

cdecl的挪用方法決議了:

(1) 參數從右向左順次壓入客棧

(2) 由挪用者恢復客棧

(3) 函數名主動加前導下劃線

因為是由挪用者來恢復客棧,是以C挪用方法許可函數的參數個數是不固定的,這是C說話的一年夜特點。

此方法的函數被翻譯為:

push b   // 先壓入第二個參數

push a   // 在壓入第一個參數

call funtion  // 挪用函數

add  esp, 8   // 清算客棧


在編譯時,此方法的函數被翻譯成:_function
 

3. fastcall

fastcall 依照名字上懂得便可以曉得,它是一種疾速挪用方法。此方法的函數的第一個和第二個DWORD參數經由過程ecx和edx傳遞,

前面的參數從右向左的次序壓入棧。

被挪用函數清算客棧。

函數名修個規矩同stdcall

其聲明語法為:

int fastcall function(int a, int b);


4. thiscall

thiscall 挪用方法是獨一一種不克不及顯示指定的潤飾符。它是c++類成員函數缺省的挪用方法。因為成員函數挪用還有一個this指針,是以必需用這類特別的挪用方法。

thiscall挪用方法意味著:

參數從右向左壓入棧。

假如參數個數肯定,this指針經由過程ecx傳遞給被挪用者;假如參數個數不肯定,this指針在一切參數壓入棧後被壓入棧。

參數個數不定的,由挪用者清算客棧,不然由函數本身清算客棧。

可以看到,關於參數個數固定的情形,它相似於stdcall,不准時則相似於cdecl。
 

5. naked call

是一種比擬少見的挪用方法,普通高等法式設計說話中不罕見。


函數的聲明挪用方法和現實挪用方法必需分歧,必定編譯器會發生凌亂。


函數名字修正規矩:

1. C編譯時函數名潤飾商定規矩:

__stdcall挪用商定在輸入函數名前加上一個下劃線前綴,前面加上一個“@”符號和其參數的字節數,格局為_function@8。

__cdecl挪用商定僅在輸入函數名前加上一個下劃線前綴,格局為_function。

__fastcall挪用商定在輸入函數名前加上一個“@”符號,前面也是一個“@”符號和其參數的字節數,格局為@function@8。

它們均不轉變輸入函數名中的字符年夜小寫,這和PASCAL挪用商定分歧,PASCAL商定輸入的函數名無任何潤飾且全體年夜寫。

2. C++編譯時函數名潤飾商定規矩:

__stdcall挪用商定:

(1)以“?”標識函數名的開端,後跟函數名;

(2)函數名前面以“@@YG”標識參數表的開端,後跟參數表;

(3)參數表以代號表現:

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--表現指針,前面的代號注解指針類型,假如雷同類型的指針持續湧現,以“0”取代,一個“0”代

表一次反復;

(4)參數表的第一項為該函數的前往值類型,厥後順次為參數的數據類型,指針標識在其所指數據類型前;

(5)參數表後以“@Z”標識全部名字的停止,假如該函數無參數,則以“Z”標識停止。

其格局為“?functionname@@YG*****@Z”或“?functionname@@YG*XZ”,例如

int Test1(char *var1,unsigned long)-----“?Test1@@YGHPADK@Z”

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


__cdecl挪用商定:

規矩同下面的_stdcall挪用商定,只是參數表的開端標識由下面的“@@YG”變成“@@YA”。
 

__fastcall挪用商定:

規矩同下面的_stdcall挪用商定,只是參數表的開端標識由下面的“@@YG”變成“@@YI”。


VC++對函數的省缺聲明是"__cedcl",將只能被C/C++挪用。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved