Nichtübereinstimmung für 'RuntimeLibrary' erkannt

114

Ich habe Crypto ++ in C: \ cryptopp heruntergeladen und extrahiert. Ich habe Visual Studio Express 2012 verwendet, um alle darin enthaltenen Projekte zu erstellen (wie in der Readme-Datei angegeben), und alles wurde erfolgreich erstellt. Dann habe ich ein Testprojekt in einem anderen Ordner erstellt und Cryptolib als Abhängigkeit hinzugefügt. Danach habe ich den Include-Pfad hinzugefügt, damit ich problemlos alle Header einschließen kann. Beim Kompilieren wurde eine Fehlermeldung zu ungelösten Symbolen angezeigt.

Um dem abzuhelfen, habe ich hinzugefügt C:\cryptopp\Win32\Output\Debug\cryptlib.lib, um zusätzliche Abhängigkeiten zu verknüpfen. Jetzt bekomme ich diesen Fehler:

Error   1   error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in program.obj    C:\Data\Work\C++ VS\CryptoTest\CryptoTest\cryptlib.lib(cryptlib.obj)    CryptoTest
Error   2   error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in program.obj    C:\Data\Work\C++ VS\CryptoTest\CryptoTest\cryptlib.lib(iterhash.obj)    CryptoTest
Error   3   error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in program.obj    C:\Data\Work\C++ VS\CryptoTest\CryptoTest\cryptlib.lib(sha.obj) CryptoTest
Error   4   error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in program.obj    C:\Data\Work\C++ VS\CryptoTest\CryptoTest\cryptlib.lib(pch.obj) CryptoTest
Error   5   error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in program.obj    C:\Data\Work\C++ VS\CryptoTest\CryptoTest\cryptlib.lib(misc.obj)    CryptoTest
Error   6   error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in program.obj    C:\Data\Work\C++ VS\CryptoTest\CryptoTest\cryptlib.lib(queue.obj)   CryptoTest
Error   7   error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in program.obj    C:\Data\Work\C++ VS\CryptoTest\CryptoTest\cryptlib.lib(algparam.obj)    CryptoTest
Error   8   error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in program.obj    C:\Data\Work\C++ VS\CryptoTest\CryptoTest\cryptlib.lib(filters.obj) CryptoTest
Error   9   error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in program.obj    C:\Data\Work\C++ VS\CryptoTest\CryptoTest\cryptlib.lib(fips140.obj) CryptoTest
Error   10  error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in program.obj    C:\Data\Work\C++ VS\CryptoTest\CryptoTest\cryptlib.lib(cpu.obj) CryptoTest
Error   11  error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in program.obj    C:\Data\Work\C++ VS\CryptoTest\CryptoTest\cryptlib.lib(mqueue.obj)  CryptoTest

Ich bekomme auch:

Error   12  error LNK2005: "public: __thiscall std::_Container_base12::_Container_base12(void)" (??0_Container_base12@std@@QAE@XZ) already defined in cryptlib.lib(cryptlib.obj)    C:\Data\Work\C++ VS\CryptoTest\CryptoTest\msvcprtd.lib(MSVCP110D.dll)   CryptoTest
Error   13  error LNK2005: "public: __thiscall std::_Container_base12::~_Container_base12(void)" (??1_Container_base12@std@@QAE@XZ) already defined in cryptlib.lib(cryptlib.obj)   C:\Data\Work\C++ VS\CryptoTest\CryptoTest\msvcprtd.lib(MSVCP110D.dll)   CryptoTest
Error   14  error LNK2005: "public: void __thiscall std::_Container_base12::_Orphan_all(void)" (?_Orphan_all@_Container_base12@std@@QAEXXZ) already defined in cryptlib.lib(cryptlib.obj)   C:\Data\Work\C++ VS\CryptoTest\CryptoTest\msvcprtd.lib(MSVCP110D.dll)   CryptoTest
Error   15  error LNK2005: "public: __thiscall std::locale::id::id(unsigned int)" (??0id@locale@std@@QAE@I@Z) already defined in cryptlib.lib(iterhash.obj) C:\Data\Work\C++ VS\CryptoTest\CryptoTest\msvcprtd.lib(MSVCP110D.dll)   CryptoTest
Warning 16  warning LNK4098: defaultlib 'LIBCMTD' conflicts with use of other libs; use /NODEFAULTLIB:library   C:\Data\Work\C++ VS\CryptoTest\CryptoTest\LINK  CryptoTest
Error   17  error LNK1169: one or more multiply defined symbols found   C:\Data\Work\C++ VS\CryptoTest\Debug\CryptoTest.exe 1   1   CryptoTest

Der Code, den ich zu kompilieren versuchte, war einfach (ich habe ihn von einer anderen Site erhalten):

#include <iostream>
#include <string>
#include "sha.h"
#include "hex.h"
using namespace std;

string SHA256(string data) {
    byte const* pbData = (byte*) data.data();
    unsigned int nDataLen = data.size();
    byte abDigest[32];

    CryptoPP::SHA256().CalculateDigest(abDigest, pbData, nDataLen);

    return string((char*)abDigest);
}

int main(void) {

    return 0;
}

Irgendwelche Ideen, wie man das behebt? Ich brauche jetzt wirklich nur SHA-256, sonst nichts. Ich verwende Windows 7 64-Bit und habe heute VS C ++ heruntergeladen, daher sollte es die neueste Version sein.

Momonga
quelle
1
Ich habe die Laufzeitbibliothek meines Projekts auf Multi-Threaded-Debug eingestellt (das war die Einstellung, die in Crypto ++ verwendet wurde) und jetzt wird sie kompiliert! :) Ich danke dir sehr.
Momonga
Die Probleme traten viel früher auf, als Sie ausgeführt wurden VCUpgrade. Sie sehen Symptome des VCUpgrade-Fehlers, der Ihnen als Erfolg gemeldet wurde .
JWW

Antworten:

233

(Dies wird bereits in Kommentaren beantwortet, aber da es keine tatsächliche Antwort gibt , schreibe ich dies.)

Dieses Problem tritt in neueren Versionen von Visual C ++ auf (die älteren Versionen haben das Programm normalerweise nur stillschweigend verknüpft und es würde zur Laufzeit abstürzen und brennen). Dies bedeutet, dass einige der Bibliotheken, die Sie mit Ihrem Programm verknüpfen (oder sogar einige der Quellen) Dateien in Ihrem Programm selbst) verwenden verschiedene Versionen der CRT (der C RunTime-Bibliothek).

Um diesen Fehler zu beheben, müssen Sie in Ihre Project Properties(und / oder die der von Ihnen verwendeten Bibliotheken) und dann in C/C++und dann Code Generationden Wert von Runtime Library; Dies sollte für alle genau gleich sein Dateien und Bibliotheken, die Sie miteinander verknüpfen . (Die Regeln für die Verknüpfung mit DLLs sind etwas entspannter, aber ich werde hier nicht auf das "Warum" und weitere Details eingehen.)

Derzeit gibt es vier Optionen für diese Einstellung:

  1. Multithread-Debug
  2. Multithread-Debug-DLL
  3. Multithread-Version
  4. Multithreaded Release DLL

Ihr spezielles Problem scheint darauf zurückzuführen zu sein, dass Sie eine mit "Multithreaded Debug" (dh statische Multithread-Debug-CRT) erstellte Bibliothek mit einem Programm verknüpfen, das mit der Einstellung "Multithreaded Debug DLL " (dh dynamische Multithread-Debug-CRT) erstellt wird. Sie sollten dies ändern Diese Einstellung entweder in der Bibliothek oder in Ihrem Programm. Im Moment schlage ich vor, dies in Ihrem Programm zu ändern.

Beachten Sie, dass Sie sicherstellen sollten, dass die Einstellungen in all diesen Projektkonfigurationen übereinstimmen, da Visual Studio-Projekte unterschiedliche Sätze von Projekteinstellungen für Debug- und Release-Builds (und 32/64-Bit-Builds) verwenden.

Für (einige) weitere Informationen können Sie diese sehen (verlinkt aus einem Kommentar oben):

  1. Linker Tools Warnung LNK4098 auf MSDN
  2. / MD, / ML, / MT, / LD (Laufzeitbibliothek verwenden) auf MSDN
  3. Erstellen Sie Fehler mit VC11 Beta - das Mischen von MTd-Bibliotheken mit MDd-Exes kann nicht auf Bugzilla @ Mozilla verlinkt werden

UPDATE : (Dies ist eine Antwort auf einen Kommentar, in dem nach dem Grund gefragt wird, warum so viel Vorsicht geboten ist.)

Wenn zwei Codeteile, die wir miteinander verknüpfen, selbst mit der Standardbibliothek verknüpft sind und diese verwenden, muss die Standardbibliothek für beide gleich sein, es sei denn, sie ist großartig Sorge um genommen wird , wie unsere zwei Codestücke interact und Daten weiter um. Im Allgemeinen würde ich sagen, dass für fast alle Situationen genau die gleiche Version der Standardbibliothekslaufzeit verwendet wird (in Bezug auf Debug / Release, Threads und natürlich die Version von Visual C ++, unter anderem wie Iterator-Debugging usw.).

Der wichtigste Teil des Problems ist folgender: Die gleiche Vorstellung von der Größe von Objekten auf beiden Seiten eines Funktionsaufrufs .

Stellen Sie sich zum Beispiel vor, dass die beiden oben genannten Codeteile Aund heißen B. A wird gegen eine Version der Standardbibliothek und B gegen eine andere kompiliert . In der Ansicht von A hat ein zufälliges Objekt, das von einer Standardfunktion zurückgegeben wird (z. B. ein Speicherblock oder ein Iterator oder ein FILEObjekt oder was auch immer), eine bestimmte Größe und ein bestimmtes Layout (denken Sie daran, dass das Strukturlayout zur Kompilierungszeit in C / festgelegt und festgelegt wird) C ++.) Aus einem von mehreren Gründen ist Bs Vorstellung von der Größe / dem Layout derselben Objekte unterschiedlich (dies kann auf zusätzliche Debug-Informationen, die natürliche Entwicklung von Datenstrukturen im Laufe der Zeit usw. zurückzuführen sein).

Wenn A nun die Standardbibliothek aufruft und ein Objekt zurückerhält, dieses Objekt an B übergibt und B dieses Objekt auf irgendeine Weise berührt, besteht die Möglichkeit, dass B dieses Objekt durcheinander bringt (z. B. das falsche Feld schreiben oder das Ende überschreiten davon usw.)

Dies ist nicht die einzige Art von Problemen, die auftreten können. Interne globale oder statische Objekte in der Standardbibliothek können ebenfalls Probleme verursachen. Und es gibt auch dunkelere Problemklassen.

All dies wird in einigen Aspekten seltsamer, wenn DLLs (dynamische Laufzeitbibliothek) anstelle von libs (statische Laufzeitbibliothek) verwendet werden.

Diese Situation kann für jede Bibliothek gelten, die von zwei zusammenarbeitenden Codeteilen verwendet wird. Die Standardbibliothek wird jedoch von den meisten (wenn nicht fast allen) Programmen verwendet, was die Wahrscheinlichkeit von Konflikten erhöht.

Was ich beschrieben habe, ist offensichtlich eine verwässerte und vereinfachte Version des eigentlichen Chaos, das Sie erwartet, wenn Sie Bibliotheksversionen mischen. Ich hoffe, es gibt Ihnen eine Vorstellung davon, warum Sie es nicht tun sollten!

yzt
quelle
Ich bin etwas verwirrt. Der Fehler von OP ist LNK2038 . Da dies nicht bei allen Bibliotheken der Fall ist, vermute ich, dass Crypto ++ mit einigen CRT-Einstellungen herumfummelt, die das Mischen von CRT-Aromen unmöglich machen - normalerweise handelt es sich nur um eine Warnung (LNK4098), und Sie sind möglicherweise sicher, wenn Sie wissen, was Sie tun (nicht empfohlen, aber mit Einschränkungen möglich, siehe z . B. stackoverflow.com/a/19944935/948581 ). Ich weiß jedoch nicht, warum Crypto ++ auf diese Weise betroffen ist.
1
@Tibo: Dies sind keine Importbibliotheken für DLLs. Ich glaube, Crypto ++ wird hier tatsächlich statisch mit dem Programm verknüpft. Dies bedeutet, dass jede Nichtübereinstimmung in der Standardbibliothek, die in einem Modul mit einem anderen Modul verknüpft ist, (wahrscheinlich) gegen die "One Definition Rule" verstößt. Was schlecht ist. Dies war früher kein Fehler, da der Linker dies nicht einmal erkennen konnte (die Funktions- / Typnamen waren dieselben, aber ihre Körper und Definitionen unterschieden sich erheblich), bis VC10, als der Linker / Bibliothekar begann, die Module zu "markieren" es produzierte mit zusätzlichen Informationen über die Konfiguration des
Builds
@Tibo: ... (Fortsetzung des vorherigen Kommentars) Sehen Sie sich beispielsweise den ersten Fehlerblock an, den das OP meldet. Dort ist " RuntimeLibrary " ein Tag sowohl in der Crypto ++ - Bibliothek als auch in der Objektdatei für das OP-Programm, und sein Wert ist " MDd_DynamicDebug " für einen von ihnen und " MTd_StaticDebug “ für den anderen. Auf diese Weise kann der Linker, der versucht, zwei Objektdateien miteinander zu verknüpfen, eine völlig neue Fehlerklasse erkennen und melden, da die Linker, die diese Objektdateien erstellt haben, sie mit relevanten Informationen versehen haben, insbesondere mit Einstellungen, die möglicherweise gegen ODR verstoßen würden.
Yzt
Obwohl ich Ihnen durchaus zustimme, gibt es hier immer noch ein mysteriöses Gebiet. Was das Problem des OP betrifft, denke ich, dass er "dll.h" aus Crypto ++ einschließt und dann versucht, anstelle der Importbibliothek der DLL eine Verknüpfung mit der statischen Bibliothek herzustellen. Aber ich habe genau die gleichen Fehler auf einem Computer gesehen, nicht auf einem anderen (VS2013 ultimative sp4 -> Fehler, VS2013 Community sp5 -> ok) ...
1
@yzt Ich habe eine Lösung gefunden. Anstatt / ZW swicth zu verwenden, bietet Windows eine Möglichkeit, die WinRT-API über COM mithilfe eines Wrappers namens WRL zu verwenden. Es ist nur so, dass die Nichtverwendung von / ZW das Codieren wenig schwierig macht, da es Details zur COM-Implementierung verbirgt, aber es ist möglich, WinRT ohne / ZW zu verwenden.
Sahil Singh
3

Ich habe Crypto ++ in C: \ cryptopp heruntergeladen und extrahiert. Ich habe Visual Studio Express 2012 verwendet, um alle darin enthaltenen Projekte zu erstellen (wie in der Readme-Datei angegeben), und alles wurde erfolgreich erstellt. Dann habe ich ein Testprojekt in einem anderen Ordner erstellt und Cryptolib als Abhängigkeit hinzugefügt.

Die Konvertierung war wahrscheinlich nicht erfolgreich. Das einzige, was erfolgreich war, war die Ausführung von VCUpgrade. Die eigentliche Konvertierung selbst ist fehlgeschlagen, aber Sie wissen es erst, wenn die aufgetretenen Fehler auftreten. Einige Details finden Sie unter Visual Studio im Crypto ++ - Wiki.


Irgendwelche Ideen, wie man das behebt?

Um Ihre Probleme zu beheben, sollten Sie herunterladen, vs2010.zipwenn Sie eine statische C / C ++ - Laufzeitverknüpfung wünschen (/MT oder /MTd) oder eine vs2010-dynamic.zipdynamische C / C ++ - Laufzeitverknüpfung ( /MToder /MTd) wünschen . Beide beheben die latenten, stillen Fehler, die von VCUpgrade verursacht werden.


vs2010.zip, vs2010-dynamic.zipUnd vs2005-dynamic.zipwerden von den eingebauten neuesten GitHub Quellen . Zum jetzigen Zeitpunkt (1. Juni 2016) ist dies effektiv vor Crypto ++ 5.6.4. Wenn Sie die ZIP-Dateien mit Crypto ++ auf niedrigerer Ebene wie 5.6.2 oder 5.6.3 verwenden, treten kleinere Probleme auf.

Mir sind zwei kleinere Probleme bekannt. Erstens ist eine Umbenennung von bench.cppzubench1.cpp . Sein Fehler ist entweder:

  • C1083: Cannot open source file: 'bench1.cpp': No such file or directory
  • LNK2001: unresolved external symbol "void __cdecl OutputResultOperations(char const *,char const *,bool,unsigned long,double)" (?OutputResultOperations@@YAXPBD0_NKN@Z)

Die Lösung besteht darin, entweder (1) zu öffnen cryptest.vcxproj im Editor zu , zu suchen bench1.cppund dann in umzubenennen bench.cpp. Oder (2) Umbenennungs bench.cppzu bench1.cppauf dem Dateisystem. Bitte löschen Sie diese Datei nicht.

Das zweite Problem ist etwas kniffliger, weil es sich um ein sich bewegendes Ziel handelt. In Versionen auf niedrigerer Ebene wie 5.6.2 oder 5.6.3 fehlen die neuesten in GitHub verfügbaren Klassen . Zu den fehlenden Klassendateien gehören HKDF (5.6.3), RDRAND (5.6.3), RDSEED (5.6.3), ChaCha (5.6.4), BLAKE2 (5.6.4), Poly1305 (5.6.4) usw.

Das Update besteht darin, die fehlenden Quelldateien aus den Visual Studio-Projektdateien zu entfernen, da sie für die untergeordneten Versionen nicht vorhanden sind.

Eine andere Möglichkeit besteht darin, die fehlenden Klassendateien aus den neuesten Quellen hinzuzufügen. Es kann jedoch zu Komplikationen kommen. Zum Beispiel hängen viele der Quellen subtil von der neuesten abconfig.h , cpu.hund cpu.cpp. Die "Subtilität" ist, dass Sie nicht merken, dass Sie eine unterdurchschnittliche Klasse bekommen.

Ein Beispiel für eine unterdurchschnittliche Klasse ist BLAKE2. config.hFügt die Kompilierungszeit für die ARM-32- und ARM-64-Erkennung hinzu. cpu.hund cpu.cppfügt eine Laufzeit-ARM-Befehlserkennung hinzu, die von der Erkennung der Kompilierungszeit abhängt. Wenn Sie BLAKE2 ohne die anderen Dateien hinzufügen, erfolgt keine Erkennung, und Sie erhalten eine direkte C / C ++ - Implementierung. Sie werden wahrscheinlich nicht bemerken, dass Sie die NEON-Gelegenheit verpassen, die etwa 9 bis 12 Zyklen pro Byte gegenüber etwa 40 Zyklen pro Byte für Vanilla C / C ++ umfasst.

jww
quelle
Ich habe die Anweisungen im Cryptopp-Wiki befolgt, vs2010-dynamic.zip heruntergeladen und den Inhalt in den cryptopp563-Code eingefügt. Erstellt und einige Quelldateien fehlen. Kein Problem, das Wiki sagt, dass die Zip-Datei für das neueste Projekt auf Github ist, und lösche einfach alle fehlenden Dateien. Gelöscht. Jetzt erstellt das Projekt einfach nicht: 4 Linkfehler, ein Beispiel: Fehler LNK2001: ungelöstes externes Symbol "void __cdecl OutputResultOperations (char const *, char const *, bool, unsigned long, double)" (? OutputResultOperations @@ YAXPBD0_NKN @ Z)
Yaniv
Es stellte sich heraus, dass eine bank.cpp im Projekt fehlte. Aber auch nach , dass es nicht kompilieren , bis ich dieses Update fiptest.cpp angewendet github.com/weidai11/cryptopp/pull/151/files?diff=split Ich wünschte , sie würden etwas Ordnung in dieses machen, fügen wie die Projekt Zip - Dateien in git oder so. Und ja, ich habe es versäumt zu sagen, dass mein Compiler VS2015 Update 2 ist. Fazit: Befolgen Sie die Hinweise, die ich geschrieben habe, und es funktioniert.
Yaniv
@Yaniv - Was empfehlen Sie für den ersten Kommentar, damit andere Benutzer keine Probleme haben? Für den zweiten Kommentar planen wir, den Patch zu nehmen, sobald wir ihn vollständig getestet haben. Können wir in der Zwischenzeit etwas tun? (Ich habe dieser Antwort zusätzliche Informationen hinzugefügt, möchte aber sicherstellen, dass Benutzer keine Probleme haben.)
JWW
Erstens, vielen Dank dafür. Crypto ++ rockt wirklich. Versuchen Sie in Bezug auf die Build-Probleme, die Windows SLN- und Projektdateien mit den neuesten Dateien im Projekt kompatibel zu halten. Da sich diese natürlich ändern, sollte dieser Windows Build irgendwie mit der Codebasis verknüpft sein und sich möglicherweise sogar im Quellbaum befinden. Wenn das zu viel ist, stellen Sie zumindest sicher, dass die Zip-Datei mit der Visual Studio-Build-Umgebung mit der aktuellen stabilen offiziellen Version kompatibel ist.
Yaniv
In Bezug auf den Patch für fiptest.cpp scheint VS2015 etwas anderes zu sein, daher muss jeder, der VS2015 verwenden möchte, diesen Patch anwenden. Es ist nur ein weiterer Fall in einem # ifdef-Block, der den richtigen Debug-Rückruf für VS2015 zu definieren scheint, und es ist wirklich einfach, manuell zu patchen.
Yaniv
3

Ich hatte dieses Problem zusammen mit einer Nichtübereinstimmung in ITERATOR_DEBUG_LEVEL. Da ein Problem am Sonntagabend immerhin in Ordnung und gut zu sein schien, wurde ich für einige Zeit aus dem Verkehr gezogen. Arbeiten in de VS2017 IDE (Projektmappen-Explorer) Ich habe kürzlich einen Quelldateiverweis zu meinem Projekt (Strg-Ziehen) aus einem anderen Projekt hinzugefügt / kopiert. Bei der Untersuchung von Eigenschaften-> C / C ++ / Präprozessor - auf Quelldateiebene, nicht auf Projektebene - habe ich festgestellt, dass in einer Release-Konfiguration _DEBUG anstelle von NDEBUG für diese Quelldatei angegeben wurde. Welches war die ganze Änderung, die nötig war, um das Problem loszuwerden.

Jan.
quelle
1

Das Problem kann durch Hinzufügen der CRT von msvcrtd.lib in der Linkerbibliothek behoben werden. Weil cryptlib.lib die CRT-Version des Debugs verwendet hat.

abhijithkp
quelle