Dekorierte Namen
Funktionen, Daten und Objekte werden in C- und C++-Programmen intern durch ihre ergänzten Namen dargestellt. Ein versehener Name ist eine codierte Zeichenfolge, die vom Compiler während der Kompilierung eines Objekts, einer Daten- oder Funktionsdefinition erstellt wird. Er zeichnet Aufrufkonventionen, Typen, Funktionsparameter und sonstige Informationen zusammen mit dem Namen auf. Diese Namensdeko, auch bekannt als Namens-Mangling, hilft dem Linker, die richtigen Funktionen und Objekte beim Verknüpfen einer ausführbaren Datei zu finden.
Die eingerichteten Benennungskonventionen haben sich in verschiedenen Versionen von Visual Studio geändert und können auch für unterschiedliche Zielarchitekturen unterschiedlich sein. Um eine ordnungsgemäße Verknüpfung mit Quelldateien herzustellen, die mit Visual Studio, C- und C++-DLLs und -Bibliotheken erstellt wurden, sollten mit demselben Compilertoolset, Flags und zielarchitektur kompiliert werden.
Hinweis
Bibliotheken, die von Visual Studio 2015 oder höher erstellt wurden, können von Anwendungen genutzt werden, die mit höheren Versionen von Visual Studio bis Visual Studio 2022 erstellt wurden. Weitere Informationen finden Sie unter C++-Binärkompatibilität zwischen Visual Studio-Versionen.
Verwenden von verzierten Namen
In der Regel müssen Sie den ergänzten Namen nicht kennen, um Code schreiben zu können, der erfolgreich kompiliert werden kann und richtige Verknüpfungen aufweist. Ergänzte Namen sind ein internes Implementierungsdetail des Compilers und Linkers. Die Tools können den Name in der Regel auch in seiner nicht ergänzten Form behandeln. Ein ergänzter Name ist jedoch manchmal erforderlich, wenn Sie einen Funktionsnamen zum Linker oder anderen Tools angeben. Um zum Beispiel überladene C++-Funktionen, Member von Namespaces, Klassenkonstruktoren, Destruktoren und spezielle Memberfunktionen angeben zu können, müssen Sie den ergänzten Namen verwenden. Ausführliche Informationen zu den Optionskennzeichnungen und anderen Situationen, die versehene Namen erfordern, finden Sie in der Dokumentation zu den Tools und Optionen, die Sie verwenden.
Wenn Sie den Funktionsnamen, die Klasse, die Aufrufkonvention, den Rückgabetyp oder einen Parameter ändern, ändert sich auch der ergänzte Name. In diesem Fall müssen Sie den neuen ergänzten Namen abrufen und ihn überall dort verwenden, wo der ergänzte Name angegeben ist.
Die Namensergänzung ist auch dann wichtig, wenn eine Verknüpfen mit Code erfolgt, der in einer anderen Programmiersprache geschrieben wurde oder andere Compiler verwendet. Verschiedene Compilern verwenden unterschiedliche Konventionen für die Namensergänzung. Wenn Ihre ausführbare Datei eine Verknüpfung zu Code enthält, der in einer anderen Sprache geschrieben wurde, müssen Sie insbesondere darauf achten, dass die exportierten und importierten Namen und Aufrufkonventionen übereinstimmen. Assemblysprachecode muss die msVC-eingerichteten Namen und Aufrufkonventionen verwenden, um mit Quellcode zu verknüpfen, der mit MSVC geschrieben wurde.
Format eines C++-dekorierten Namens
Ein ergänzter Name für eine C++-Funktion enthält die folgenden Informationen:
Der Funktionsname.
Die Klasse, bei der es sich bei der Funktion um ein Element handelt, wenn es sich um eine Memberfunktion handelt. Die Dekoration kann die Klasse enthalten, die die Klasse umschließt, die die Funktion enthält usw.
Der Namespace, zu dem die Funktion gehört, wenn sie Teil eines Namespaces ist.
Die Typen der Funktionsparameter.
Die Aufrufkonvention.
Der Rückgabetyp der Funktion.
Ein optionales zielspezifisches Element. In ARM64EC Objekten wird ein
$$h
Tag in den Namen eingefügt.
Die Namen der Funktion und der Klasse werden im ergänzten Namen codiert. Der Rest des ergänzten Namens ist ein Code, der nur für den Compiler und Linker eine interne Bedeutung hat. Es folgen Beispiele für nicht ergänzte und ergänzte Namen in C++.
Nicht ergänzter Name | Ergänzter Name |
---|---|
int a(char){int i=3;return i;}; |
?a@@YAHD@Z |
void __stdcall b::c(float){}; |
?c@b@@AAGXM@Z |
Format eines mit C versehenen Namens
Das Format einer Ergänzung für eine C-Funktion hängt von der Aufrufkonvention ab, die in der Deklaration verwendet wird. Dies isst in der folgenden Tabelle dargestellt. Es ist auch das Dekorationsformat, das verwendet wird, wenn C++-Code als Verknüpfung deklariert extern "C"
wird. Die Standardaufrufkonvention ist __cdecl
. In einer 64-Bit-Umgebung sind C oder extern "C"
Funktionen nur bei Verwendung der __vectorcall
Aufrufkonvention versehen.
Aufrufkonvention | Dekoration |
---|---|
__cdecl |
Vorangestellter Unterstrich (_ ) |
__stdcall |
Führende Unterstriche (_ ) und ein nachfolgendes At-Zeichen (@ ) gefolgt von der Anzahl der Bytes in der Parameterliste im Dezimaltrennzeichen |
__fastcall |
Führende und nachgestellte Zeichen (@ ) gefolgt von einer Dezimalzahl, die die Anzahl der Bytes in der Parameterliste darstellt |
__vectorcall |
Zwei nachgestellte Zeichen (@@ ) gefolgt von einer Dezimalzahl von Bytes in der Parameterliste |
Bei ARM64EC Funktionen mit C-Verknüpfung (ob als C oder mithilfe extern "C"
von C kompiliert) wird dem versehenen Namen eine #
vorangestellt.
Anzeigen von verzierten Namen
Sie erhalten das ergänzte Format eines Symbolnamens, wenn Sie die Quelldatei mit den Daten, dem Objekt oder der Funktionsdefinition bzw. dem Prototypen kompiliert haben. Um ergänzte Namen im Programm zu untersuchen, können Sie eine der folgenden Methoden verwenden:
Verwenden einer Auflistung zum Anzeigen ergänzter Namen
Generieren Sie eine Auflistung, indem Sie die Quelldatei kompilieren, die die Daten, Objekte oder Funktionsdefinitionen oder den Prototyp enthält, wobei die
/FA
Compileroption (Eintragsdateityp) auf Assembly mit Quellcode (/FAs
) festgelegt ist.Geben Sie
cl /c /FAs example.cpp
beispielsweise an einer Entwickler-Eingabeaufforderung ein, um eine Eintragsdatei zu generieren.example.asm
Suchen Sie in der resultierenden Eintragsdatei die Zeile, die mit
PUBLIC
einem Semikolon (;
) beginnt und endet, gefolgt von den nicht berechneten Daten oder Funktionsnamen. Das Symbol zwischenPUBLIC
und dem Semikolon ist der verzierte Name.
Verwenden von DUMPBIN zum Anzeigen von ergänzten Namen
Um die exportierten Symbole in einer OBJ- oder LIB-Datei anzuzeigen, geben Sie
dumpbin /exports <obj-or-lib-file>
an einer Entwickler-Eingabeaufforderung ein.Um das ergänzte Format eines Symbols zu finden, suchen Sie nach dem nicht ergänzten Namen in Klammern. Der verzierte Name befindet sich in derselben Zeile, vor dem nicht verstrichenen Namen.
Nicht bewertete Namen anzeigen
Mit „undname.exe“ können Sie einen ergänzten Namen in das nicht ergänzte Format konvertieren. Dieses Beispiel zeigt, wie dies funktioniert:
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)"
Siehe auch
Zusätzliche MSVC-Buildtools
Verwenden extern
zum Angeben der Verknüpfung