Freigeben über


Namenszerlegung im alten Stil für exportierte Vorlageninstanziierungen

Aktualisiert: November 2007

Ein Aspekt der Visual C++-Konformitätsverbesserung ist das Zulassen des Überladens von Spezialisierungen von Funktionsvorlagen und regulären Vorlagen.

Der folgende Beispielcode wird z. B. in Visual Studio .NET 2003 kompiliert, verursacht in Visual Studio .NET jedoch einen Fehler:

// bc_exported_templ_instan.cpp
template<typename T, typename U>
T ConvertTo(const U &u) {
   return static_cast<T>(u);
}

char ConvertTo(const int &i) {
   return static_cast<char>(i);
}

int main() {
   char c1 = ConvertTo(1);
   char c2 = ConvertTo<char, int>(2);
}

Um das Überladen von Spezialisierungen von Funktionsvorlagen und regulären Vorlagen zu unterstützen, wurde das Verfahren geändert, mit dem der Compiler ergänzte Namen für Spezialisierungen von Funktionsvorlagen erstellt. In einem aktualisierten ergänzten Namen sind jetzt die Vorlagenargumente sowie die Funktionsparameter und Rückgabetypen codiert. Für die Funktionen im vorhergehenden Beispiel generiert der C++-Compiler in Visual Studio .NET 2003 die folgenden Namensergänzungen:

?ConvertTo@@YADABH@Z      – char ConvertTo(const int &);
??$ConvertTo@DH@@YADABH@Z – char ConvertTo<char, int>(const int &);

Dies sollte nicht implizieren, dass sich bei Ihrer Vorgehensweise bei der Entwicklung von Anwendungen etwas ändert. Ein Bereich, in dem diese Änderung sich auf Benutzer auswirkt, sind Fälle, in denen der Export eine Spezialisierung einer Funktionsvorlage aus einer DLL ist, die in einer Anwendung verwendet wird, die nicht mit dem neuen Compiler neu kompiliert wurde. Hierzu ein Beispiel:

// bc_exported_templ_instan2.h
#include <iostream>
#ifdef _DLL_EXPORT
#define DLL_LINKAGE __declspec(dllexport)
#else
#define DLL_LINKAGE __declspec(dllimport)
#endif

template<typename T>
void f(const T &rT) {
   std::cout << "i = " << rT << std::endl;
}
template DLL_LINKAGE void f<int>(const int &);

Der folgende Code wird kompiliert, um die DLL zu erstellen:

// bc_exported_templ_instan2.cpp
// compile with: /D_DLL_EXPORT /EHsc /LD
#include "bc_exported_templ_instan2.h"

Wenn Sie dann Folgendes ausführen:

dumpbin /exports bc_exported_templ_instan2.dll

sehen Sie, dass der ergänzte Name der exportierten Spezialisierung der Funktionsvorlage ??$f@H@@YAXABH@Z ist.

Wenn eine vorhandene Anwendung von dieser DLL abhängt, diese Anwendung mit dem Visual C++-Compiler in Visual Studio .NET (oder einer früheren Version) erstellt wurde und nicht erneut erstellt werden kann oder soll, wird ein Laufzeitfehler ausgegeben, da die Anwendung einen Einstiegspunkt mit dem alten Namen erwartet. Die neue DLL exportiert jedoch nur eine Funktion mit dem neuen Namen.

// bc_exported_templ_instan3.cpp
// compile with: /EHsc /link bc_exported_templ_instan2.lib
#include "bc_exported_templ_instan2.h"
int main() {
   f(1);
}

Dieses Problem kann damit behoben werden, dass die Vorgehensweise bei der Erstellung der DLL geändert wird, damit sie sowohl den alten als auch den neuen Namen für die Spezialisierung der Funktionsvorlage exportiert. Dies geschieht durch Verwendung von /export für das Linkprogramm. Hierzu ein Beispiel:

cl /D_DLL_EXPORT /EHsc /LD a.cpp /link /export:?f@@YAXABH@Z=??$f@H@@YAXABH@Z 

Damit wird der Link angewiesen, einen Export für beide angegebenen Namen zu erstellen, jedoch zu veranlassen, dass sie demselben Symbol zugeordnet werden.

Siehe auch

Referenz

Wichtige Änderungen im Visual C++-Compiler