首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

DLL 全面剖析(三):調用約定與名字修飾深度解析

     編輯:VC 教學

調用約定:參數傳遞與棧平衡的協定

調用約定決定:參數入棧順序、誰負責清理棧、函數名修飾規則。常見約定對比:

約定關鍵字參數入棧棧清理者名字修飾 (C)名字修飾 (C++)適用場景
__stdcall__stdcall / WINAPI右→左被調用者_Func@N?Func@@YG...@ZWin32 API、COM、回調函數
__cdecl__cdecl右→左調用者_Func?Func@@YA...@ZC/C++ 默認、可變參數函數
__fastcall__fastcall前兩個 DWORD 用 ECX/EDX,其餘右→左入棧被調用者@Func@N?Func@@YI...@Z高性能需求、編譯器優化
thiscall(隱式)this 指針在 ECX,參數右→左調用者N/A?Func@@QA...@ZC++ 非靜態成員函數
naked call__declspec(naked)由程序員手寫序言/結語程序員無修飾無修飾裸機編程、中斷處理、Hook

關鍵點

  • WINAPI 宏在 Windows.h 中定義為 __stdcall,編寫自定義 API 時建議使用。
  • VC++ 默認 /Gd (__cdecl)。可在項目屬性 C/C++ → Code Generation → Calling Convention 修改,或函數級指定關鍵字(優先級高於項目設置)。
  • 命令行選項:/Gz (__stdcall)、/Gd (__cdecl)、/Gr (__fastcall)。

名字修飾:編譯器的內部身份證

修飾名由 函數名、類名、調用約定、返回類型、參數類型/順序 共同決定。C++ 重載、模板、命名空間極大增加了修飾複雜度。

C 編譯修飾規則

  • __stdcall:_FunctionName@ByteCount(如 _Add@8)
  • __cdecl:_FunctionName(僅前綴下劃線)
  • __fastcall:@FunctionName@ByteCount(前綴 @)
  • 均保持大小寫,不同於 Pascal 全大寫無修飾。

C++ 編譯修飾規則(MSVC 內部編碼)

格式:?FunctionName@@[修飾碼]

  • 開頭:? 標識函數名開始。
  • 調用約定標識:
    • @@YG:__stdcall 全局/靜態函數
    • @@YA:__cdecl 全局/靜態函數
    • @@YI:__fastcall 全局/靜態函數
    • 成員函數另有 @@QA、@@AA 等(thiscall 相關)。
  • 類型編碼(部分):
    代碼類型
    Xvoid
    Dchar
    Eunsigned char
    Fshort
    Hint
    Iunsigned int
    Jlong
    Kunsigned long
    Mfloat
    Ndouble
    _Nbool
    PA指針前綴,後跟指向類型代碼
    0重複類型標記(節省空間)
  • 參數表:第一項為返回類型,依此為各參數類型。指針標記在所指類型前。
  • 結束標記:@Z(有參數)或 Z(無參數)。

示例


查看修飾名工具

  • DUMPBIN /SYMBOLS file.obj
  • DUMPBIN /EXPORTS file.dll
  • 鏈接器生成 .map 文件(/MAP 選項)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved