__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 可以用下面的預設引數的函式來替代...