2017-05-12 2 views
1

Ich versuche, C++ - Code von Drittanbietern mit Visual Studio 2017 (Aktualisierung von Visual Studio 6.0) in meine 32-Bit-C++ - Anwendung zu kompilieren. Ich habe .h-Dateien und eine .lib-Datei von der dritten Partei. Der Linker findet die Bibliothek, aber er findet die darin enthaltenen verzierten Namen nicht. Es scheint zu sein, weil der Compiler "__int8" durch "char" ersetzt.Dekorierter Name für Funktion, die nicht ordnungsgemäß generiert wurde

Der Linker Fehler ist:

LNK2019 unresolved external symbol "signed char __cdecl Check_The_Thing(void)" ([email protected]@YACXZ) referenced in function (redacted) 

die Funktion im .h definiert ist:

_declspec(dllexport) API_RETURN_TYPE Check_The_Thing (void); 

API_RETURN_TYPE im .h definiert ist:

_declspec(dllimport) typedef signed __int8 int_8; 
_declspec(dllimport) typedef   int_8 API_RETURN_TYPE; 

Verwendung dumpbin/Exporte, kann ich sehen, dass meine lib und zugehörige dll exportiert Check_The_Thing:

[email protected]@YA_DXZ (__int8 __cdecl Check_The_Thing(void)) 

Mit undname, kann ich sehen, dass die ergänzten Namen in dem lib evaulates richtig:

Undecoration of :- "[email protected]@YA_DXZ" 
is :- "__int8 __cdecl Check_The_Thing(void)" 

Aber der Compiler generierte ergänzte Name nicht richtig bewerten (basierend auf dem Code):

Undecoration of :- "[email protected]@YACXZ" 
is :- "signed char __cdecl Check_The_Thing(void)" 

Laut https://en.wikiversity.org/wiki/Visual_C%2B%2B_name_mangling wird das "C" in YACXZ zu "signed char" und das "_D" zu "__int8" ausgewertet. Was ich nicht herausfinden kann ist, warum der Compiler API_RETURN_TYPE als "char" statt "__int8" interpretiert. Es ist klar, dass die lib/dll-Exporte "_C" anstelle von "_D" haben sollten, da API_RETURN_TYPE ein "signiertes __int8" und nicht nur "__int8" ist.

Ich habe mit einem Haufen der Compiler-Einstellungen mit Glück getüftelt. Wie hier vorgeschlagen (Cannot find decorated function name in dll), stellte ich sicher, dass ich MBCS anstelle von Unicode verwendete (vorher war es nicht gesetzt), aber das machte auch keinen Unterschied.

Das spezielle Definieren von API_RETURN_TYPE als __int8 macht keinen Unterschied, außer das "C" in ein "D" (Fortschritt!) Zu ändern. Undname zeigt den Rückgabetyp als "char" anstelle von "signed char". Das Ändern des Rückgabetyps der Funktionsdefinition in __int8 hat den gleichen Effekt wie das Ändern von API_RETURN_TYPE.

Also meine Frage: Wie kann ich den Compiler zwingen, meine Exporte mit "__int8" (oder "_D") anstelle von char ("D") richtig zu definieren?

Randnotiz: der Linker-Fehler ist der gleiche für die Fälle, in denen __int16, __int32 und __int64 verwendet werden.

EDIT: Eigentlich definiert die Bibliothek __int64 Arten, aber ich benutze keine. Es gibt keine __int64 Linkfehler.

Antwort

0

Zumindest seit Visual Studio 2003 (!), "The __int8 data type is synonymous with type char".

Offensichtlich kann der Compiler nicht verschiedene Namen mangling für zwei Möglichkeiten haben, den gleichen Typ zu benennen.

auch einsichtig ist this page die zeigt, dass __int8 ist (signiert) char aber __int64 ist nichtlong long; Letztere sind nur gleichwertig.

+0

Danke für die Antwort. Dies ist die Information, die ich auch gefunden habe. Ich hätte gedacht, dass der Linker "_D" mit "D" übereinstimmen würde, wenn es auch ist. Vielleicht verhält sich nur der Compiler so. – philselmer

+0

@philselmer: Das ergibt keinen Sinn: Da es sich um Synonyme handelt, kann es nur Namensmangel geben. Genau wie 'long int' und' long' sind zwei Synonyme für einen Typ, und daher werden die gleichen gemangelt. Es gibt jedoch keinen Grund anzunehmen, dass VS6 denselben Namen wie VS2017 verwendet. – MSalters

+0

Was der Compiler tut ist, dem Linker mitzuteilen, dass "_D" und "D" gleich sind, also wird "D" verwendet. Aber der Linker findet "_D" und versteht nicht, dass es dasselbe wie "D" ist. Wenn MS den Compiler veranlassen soll, die gleichen verfälschten Namen für __int8 und char zu erzeugen, sollte der Linker die entstellten Namen für beide verstehen. EDIT: Ich denke, ich bin unvernünftig zu erwarten VS2003 und bis zu verstehen _D, weil sie nicht mehr generieren. – philselmer

Verwandte Themen