裝飾名稱

C 和 C++ 程式中的函式、資料和物件在內部以其裝飾名稱表示。 裝飾名稱 是編譯物件、資料或函式定義期間,編譯器所建立的編碼字串。 它會記錄呼叫慣例、類型、函式參數和其他資訊,並連同名稱一起記錄。 這個名稱裝飾也稱為 名稱整改 ,可協助連結器在連結可執行檔時尋找正確的函式和物件。

裝飾的命名慣例已在各種 Visual Studio 版本中變更,而且在不同的目標架構上也可以不同。 若要正確連結使用 Visual Studio 所建立的來源檔案,應該使用相同的編譯器工具組、旗標和目標架構來編譯 C 和 C++ DLL 和程式庫。

注意

Visual Studio 2015 或更新版本所建置的程式庫,可透過 Visual Studio 2022 透過 Visual Studio 2022 使用以較新版本 Visual Studio 建置的應用程式使用。 如需詳細資訊,請參閱 Visual Studio 版本 之間的 C++ 二進位相容性。

使用裝飾名稱

通常,您在撰寫程式碼時不必知道裝飾名稱,也能成功編譯和連結。 裝飾名稱是編譯器和連結器內部的實作詳細資料。 這些工具通常能夠處理未裝飾的名稱。 不過,當您指定函式名稱給連結器和其他工具時,有時需要裝飾名稱。 比方說,若要符合多載 C++ 函式、命名空間的成員、類別建構函式、解構函式和特殊成員函式,您必須指定裝飾名稱。 如需選項旗標和其他需要裝飾名稱之情況的詳細資訊,請參閱您使用之工具和選項的檔。

如果您變更函式名稱、類別、呼叫慣例、傳回型別或任何參數,裝飾名稱也會變更。 在此情況下,您必須取得新的裝飾名稱,並在指定裝飾名稱的每個地方使用。

在連結至以其他程式設計語言撰寫的程式碼或使用其他編譯器時,名稱裝飾也很重要。 不同編譯器會使用不同的名稱裝飾慣例。 當您的執行檔連結至以另一種語言撰寫的程式碼時,必須特別注意符合匯出和匯入的名稱和呼叫慣例。 元件語言程式碼必須使用 MSVC 裝飾的名稱和呼叫慣例,連結至使用 MSVC 撰寫的原始程式碼。

C++ 裝飾名稱的格式

C++ 函式的裝飾名稱包含下列資訊:

  • 函式名稱。

  • 如果函式是成員函式,則為 的類別。 裝飾可能包含包含函式之類別的 類別等等。

  • 如果函式是命名空間的一部分,則函式所屬的命名空間。

  • 函式參數的類型。

  • 呼叫慣例。

  • 函式的傳回型別。

  • 選擇性的目標特定專案。 在 ARM64EC 物件中,標記 $$h 會插入名稱中。

函式和類別名稱是以裝飾名稱編碼。 裝飾名稱的其餘部分是只在編譯器和連結器內部才有意的代碼。 以下是 C++ 未裝飾和裝飾名稱的範例。

未裝飾名稱 裝飾名稱
int a(char){int i=3;return i;}; ?a@@YAHD@Z
void __stdcall b::c(float){}; ?c@b@@AAGXM@Z

C 裝飾名稱的格式

C 函式的裝飾形式取決於它的宣告中所使用的呼叫慣例,如下表所示。 這也是當 C++ 程式碼宣告為具有 extern "C" 連結時所使用的裝飾格式。 預設呼叫慣例是 __cdecl。 在 64 位的環境中,C 或 extern "C" 函式只有在使用 __vectorcall 呼叫慣例時才會裝飾。

呼叫慣例 裝飾
__cdecl 前置底線 ( _
__stdcall 前置底線 ( _ ) 和尾端符號 ( @ ) 後面接著十進位參數清單中的位元組數目
__fastcall 符號的前置和尾端 ( @ ) 後面接著十進位數,代表參數清單中的位元組數目
__vectorcall 兩個尾端符號 ( @@ ) 後面接著參數清單中的十進位位元組數

對於具有 C 連結的ARM64EC函式(無論是編譯為 C 還是使用 extern "C" ),前面 # 會加上裝飾名稱。

檢視裝飾名稱

在編譯包含資料、物件或函式定義或原型的原始程式檔之後,您可以取得裝飾形式的符號名稱。 若要檢查您程式中的裝飾名稱,您可以使用下列任何一個方法:

使用清單檢視裝飾名稱

  1. 藉由編譯包含資料、物件或函式定義或原型的來源檔案來產生清單,並將 /FA [列出檔案類型] 編譯器選項設定為具有原始程式碼的元件 ( /FAs )。

    例如,在開發人員命令提示字元中輸入 cl /c /FAs example.cpp ,以產生清單檔案 example.asm

  2. 在產生的清單檔案中,尋找開頭 PUBLIC 為 和 結尾的分號 ( ; ) 的行,後面接著未編碼的資料或函式名稱。 和 分號之間的 PUBLIC 符號是裝飾名稱。

使用 DUMPBIN 檢視裝飾名稱

  1. 若要查看 OBJ 或 LIB 檔案中匯出的符號,請在開發人員命令提示字元中輸入 dumpbin /exports <obj-or-lib-file>

  2. 若要尋找裝飾形式的符號,請尋找括號中的未裝飾名稱。 裝飾名稱位於同一行,在未編碼的名稱之前。

檢視未編碼的名稱

您可以使用 undname.exe 將裝飾名稱轉換成未裝飾形式。 此範例示範它的運作方式:

C:\>undname ?func1@a@@AAEXH@Z
Microsoft (R) C++ Name Undecorator
Copyright (C) Microsoft Corporation. All rights reserved.

Undecoration of :- "?func1@a@@AAEXH@Z"
is :- "private: void __thiscall a::func1(int)"

另請參閱

其他 MSVC 建置工具
使用 extern 來指定連結