C 函式的 stdcall cdecl和

2021-10-24 04:47:39 字數 1440 閱讀 5753

__stdcall、__cdecl和__fastcall是三種函式呼叫協議,函式呼叫協議會影響函式引數的入棧方式棧內資料的清除方式編譯器函式名的修飾規則等。

__stdcall:windows api預設的函式呼叫協議。

__cdecl:c/c++預設的函式呼叫協議。

__fastcall:適用於對效能要求較高的場合。

__stdcall:函式引數由右向左入棧。

__cdecl:函式引數由右向左入棧。

__fastcall:從左開始不大於4位元組的引數放入cpu的ecx和edx暫存器,其餘引數從右向左入棧。

問題一:__fastcall在暫存器中放入不大於4位元組的引數,故效能較高,適用於需要高效能的場合。

__stdcall:函式呼叫結束後由被呼叫函式清除棧內資料。

__cdecl:函式呼叫結束後由函式呼叫者清除棧內資料。

__fastcall:函式呼叫結束後由被呼叫函式清除棧內資料。

問題一:不同編譯器設定的棧結構不盡相同,跨開發平台時由函式呼叫者清除棧內資料不可行。

問題二:某些函式的引數是可變的,如printf函式,這樣的函式只能由函式呼叫者清除棧內資料。

問題三:由呼叫者清除棧內資料時,每次呼叫都包含清除棧內資料的**,故可執行檔案較大。

__stdcall:編譯後,函式名被修飾為「_functionname@number」。

__cdecl:編譯後,函式名被修飾為「_functionname」。

__fastcall:編譯後,函式名給修飾為「@functionname@nmuber」。

注:「functionname」為函式名,「number」為引數位元組數。

注:函式實現和函式定義時如果使用了不同的函式呼叫協議,則無法實現函式呼叫。

__stdcall:編譯後,函式名被修飾為「?functionname@@yg******@z」。

__cdecl:編譯後,函式名被修飾為「?functionname@@ya******@z」。

__fastcall:編譯後,函式名被修飾為「?functionname@@yi******@z」。

注:「******」為函式返回值型別和引數型別表。

注:函式實現和函式定義時如果使用了不同的函式呼叫協議,則無法實現函式呼叫。

c語言和c++語言間如果不進行特殊處理,也無法實現函式的互相呼叫。

函式呼叫的幾個概念 stdcall, cdecl

fastcall呼叫約定在輸出函式名前加上乙個 符號,後面也是乙個 符號和其引數的位元組數,格式為 functionname number。它們均不改變輸出函式名中的字元大小寫,這和pascal呼叫約定不同,pascal約定輸出的函式名無任何修飾且全部大寫。b c 編譯時函式名修飾約定規則 stdc...

C 函式的用法 erase函式

前面的文章中提到過如何向容器中新增元素,這裡介紹乙個如何刪除容器中元素的函式,包括順序容器和關聯容器。就是這個erase函式,基本用法如下 c.erase p 從c中刪除迭代器p指定的元素,p必須指向c中的乙個真實元素,不能等於c.end c.erase b,e 從c中刪除迭代器對b和e所表示的範圍...

C 函式 預設引數的函式

1 預設引數的目的 c 可以給函式定義預設引數值。通常,呼叫函式時,要為函式的每個引數給定對應的實參。例如 void delay int loops 函式宣告 void delay int loops 函式定義 void point int a void point 可以用下面的預設引數的函式來替代...