Mismatch gedetecteerd voor ‘RuntimeLibrary’

Ik heb Crypto++ gedownload en uitgepakt in C:\cryptopp. Ik heb Visual Studio Express 2012 gebruikt om alle projecten binnenin te bouwen (volgens de instructies in readme), en alles is met succes gebouwd. Daarna heb ik een testproject in een andere map gemaakt en cryptolib als afhankelijkheid toegevoegd. Daarna heb ik het include-pad toegevoegd, zodat ik gemakkelijk alle headers kan opnemen. Toen ik probeerde te compileren, kreeg ik een foutmelding over onopgeloste symbolen.

Om dat te verhelpen heb ik C:\cryptopp\Win32\Output\Debug\cryptlib.libtoegevoegd om extra afhankelijkheden te koppelen. Nu krijg ik deze foutmelding:

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

Ik krijg ook:

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

De code die ik probeerde te compileren was eenvoudig (ik heb deze van een andere site):

#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;
}

Enig idee hoe dit op te lossen? Ik heb nu echt alleen SHA-256 nodig, verder niets.
Ik gebruik Windows 7 64 bit en ik heb vandaag VS C++ gedownload, dus het zou de nieuwste versie moeten zijn.


Antwoord 1, autoriteit 100%

(Dit is al beantwoord in opmerkingen, maar omdat er geen echt antwoordis, schrijf ik dit.)

Dit probleem doet zich voor in nieuwere versies van Visual C++ (de oudere versies koppelden het programma gewoonlijk gewoon in stilte en het crashte en brandde tijdens runtime.) Het betekent dat sommige van de bibliotheken die u aan uw programma koppelt (of zelfs sommige van de bronbestanden in uw programma zelf) gebruiken verschillende versies van de CRT (de C RunTime-bibliotheek.)

Om deze fout te corrigeren, moet u naar uw Project Propertiesgaan (en/of die van de bibliotheken die u gebruikt) en vervolgens naar C/C++en vervolgens Code Generation, en controleer de waarde van Runtime Library; dit zou precies hetzelfde moeten zijn voor allebestanden en bibliotheken die u aan elkaar koppelt. (De regels zijn wat soepeler voor het koppelen met DLL’s, maar ik ga hier niet in op het “waarom” en in meer details.)

Er zijn momenteel vier opties voor deze instelling:

  1. Multithreaded foutopsporing
  2. Multithreaded Debug DLL
  3. Multithreaded release
  4. Multithreaded release-DLL

Uw specifieke probleem lijkt voort te komen uit het feit dat u een bibliotheek die is gebouwd met “Multithreaded Debug” (dwz statische multithreaded debug CRT) koppelt aan een programma dat wordt gebouwd met behulp van de instelling “Multithreaded Debug DLL” ( dwz dynamische multithreaded debug CRT.) U moet deze instelling wijzigen in de bibliotheek of in uw programma. Voor nu raad ik aan dit in je programma te wijzigen.

Merk op dat aangezien Visual Studio-projecten verschillende sets projectinstellingen gebruiken voor debug- en release-builds (en 32/64-bits builds), u ervoor moet zorgen dat de instellingen overeenkomen in al deze projectconfiguraties.

Voor (enige) meer informatie kun je deze bekijken (gelinkt vanuit een opmerking hierboven):

  1. Waarschuwing linkerhulpprogramma’s LNK4098op MSDN
  2. /MD, /ML, /MT , /LD (Gebruik runtime-bibliotheek)op MSDN
  3. Build-fouten met VC11 Beta – het mixen van MTd-bibliotheken met MDd-exe’s kan niet worden gelinktop Bugzilla@Mozilla

UPDATE: (Dit is een reactie op een opmerking waarin wordt gevraagd waarom er zoveel zorg moet worden besteed.)

Als twee stukjes code die we aan elkaar koppelen, zelf linken naar en gebruikmaken van de standaardbibliotheek, dan moet de standaardbibliotheek voor beide hetzelfde zijn, tenzij er grotezorg wordt besteed aan de manier waarop onze twee codestukken werken samen en geven gegevens door. Over het algemeen zou ik zeggen dat je voor bijna alle situaties precies dezelfde versie van de standaard bibliotheekruntime gebruikt (met betrekking tot debug/release, threads en uiteraard de versie van Visual C++, onder andere zoals iterator-foutopsporing, enz.)

Het belangrijkste deel van het probleem is dit: hetzelfde idee hebben over de grootte van objecten aan weerszijden van een functieaanroep.

Bedenk bijvoorbeeld dat de bovenstaande twee stukjes code Aen Bheten. A wordt gecompileerdtegen de ene versie van de standaardbibliotheek, en B tegen een andere. In de weergave van A heeft een willekeurig object waarnaar een standaardfunctie terugkeert (bijvoorbeeld een geheugenblok of een iterator of een FILE-object of wat dan ook) een bepaalde grootte en lay-out (onthoud dat de structuurlay-out wordt bepaald en gerepareerd tijdens het compileren in C/C++.) Om verschillende redenen is B’s idee van de grootte/lay-out van dezelfde objecten anders (het kan zijn vanwege aanvullende foutopsporingsinformatie, natuurlijke evolutie van gegevensstructuren in de loop van de tijd, enz. )

Als nu A de standaardbibliotheek aanroept en een object terugkrijgt en dat object vervolgens doorgeeft aan B, en B dat object op wat voor manier dan ook aanraakt, is de kans groot dat B dat object verprutst (bijv. het verkeerde veld schrijven, of voorbij het einde, enz.)

Het bovenstaande is niet het enige soort problemen dat kan optreden. Interne globale of statische objecten in de standaardbibliotheek kunnen ook problemen veroorzaken. En er zijn ook meer obscure klassen van problemen.

Dit alles wordt in sommige opzichten vreemder bij het gebruik van DLL’s (dynamische runtime-bibliotheek) in plaats van libs (statische runtime-bibliotheek.)

Deze situatie kan van toepassing zijn op elke bibliotheek die wordt gebruikt door twee stukjes code die samenwerken, maar de standaardbibliotheek wordt gebruikt door de meeste (zo niet bijna alle) programma’s, en dat vergroot de kans op botsingen.

Wat ik heb beschreven is duidelijk een verwaterde en vereenvoudigde versie van de eigenlijke puinhoop die je te wachten staat als je bibliotheekversies mixt. Ik hoop dat het je een idee geeft waarom je het niet zou moeten doen!


Antwoord 2, autoriteit 3%

Ik had dit probleem en kwam niet overeen in ITERATOR_DEBUG_LEVEL.
Omdat een zondagavondprobleem toch goed leek en goed was om te gaan, werd ik een tijdje uitgeschakeld.
Werkend in de VS2017 IDE (Solution Explorer) Ik had onlangs een bronbestandverwijzing naar mijn project toegevoegd/gekopieerd (ctrl-drag) uit een ander project. Kijkend naar eigenschappen->C/C++/Preprocessor – op bronbestandsniveau, niet op projectniveau– merkte ik dat in een releaseconfiguratie _DEBUG werd gespecificeerd in plaats van NDEBUG voor dit bronbestand.
Dat was de enige verandering die nodig was om van het probleem af te komen.


Antwoord 3

Ik heb Crypto++ gedownload en uitgepakt in C:\cryptopp. Ik heb Visual Studio Express 2012 gebruikt om alle projecten binnenin te bouwen (volgens de instructies in readme), en alles is met succes gebouwd. Daarna heb ik een testproject in een andere map gemaakt en cryptolib als afhankelijkheid toegevoegd.

De conversie is waarschijnlijk niet gelukt. Het enige dat succesvol was, was het draaien van VCUpgrade. De daadwerkelijke conversie zelf is mislukt, maar u weet het pas als u de fouten ervaart die u ziet. Zie Visual Studioop de Crypto++-wiki voor enkele details.


Enig idee hoe dit op te lossen?

Om uw problemen op te lossen, moet u vs2010.zipdownloaden als u statische C/C++ runtime-koppelingen wilt (/MTof /MTd), of vs2010-dynamic.zipals u dynamische C/C++ runtime-koppelingen wilt (/MTof /MTd). Beide repareren de latente, stille storingen veroorzaakt door VCUpgrade.


vs2010.zip, vs2010-dynamic.zipen vs2005-dynamic.zipzijn opgebouwd uit de nieuwste GitHub-bronnen. Op het moment van schrijven (1 juni 2016) is dat in feite pre-Crypto++ 5.6.4. Als je de ZIP-bestanden gebruikt met een lager niveau van Crypto++, zoals 5.6.2 of 5.6.3, dan zul je kleine problemen tegenkomen.

Er zijn twee kleine problemen die ik ken. De eerste is een hernoeming van bench.cppnaar bench1.cpp. De fout is ofwel:

  • 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)

De oplossing is om ofwel (1) cryptest.vcxprojin kladblok te openen, bench1.cppte zoeken en het vervolgens te hernoemen naar bench.cpp. Of (2) hernoem bench.cppnaar bench1.cppop het bestandssysteem. Verwijder dit bestand niet.

Het tweede probleem is een beetje lastiger omdat het een bewegend doelwit is. Lagere releases, zoals 5.6.2 of 5.6.3, missen de nieuwste klassen die beschikbaar zijn in GitHub. De ontbrekende klassenbestanden zijn HKDF (5.6.3), RDRAND (5.6.3), RDSEED (5.6.3), ChaCha (5.6.4), BLAKE2 (5.6.4), Poly1305 (5.6.4), enz.

De oplossing is om de ontbrekende bronbestanden uit de Visual Studio-projectbestanden te verwijderen, aangezien ze niet bestaan ​​voor de lagere releases.

Een andere optie is om de ontbrekende klassenbestanden van de nieuwste bronnen toe te voegen, maar er kunnen complicaties optreden. Veel van de bronnen zijn bijvoorbeeld subtiel afhankelijk van de nieuwste config.h, cpu.hen cpu.cpp. De “subtiliteit” is dat je je niet realiseert dat je een slecht presterende les krijgt.

Een voorbeeld van een onderpresterende klasse is BLAKE2. config.hvoegt compile-time ARM-32 en ARM-64 detectie toe. cpu.hen cpu.cppvoegen runtime ARM-instructiedetectie toe, die afhankelijk is van detectie van compileertijd. Als u BLAKE2 toevoegt zonder de andere bestanden, vindt geen van de detectie plaats en krijgt u een rechtstreekse C/C++-implementatie. Je zult je waarschijnlijk niet realiseren dat je de NEON-mogelijkheid mist, die ongeveer 9 tot 12 cycles-per-byte versus 40 cycles-per-byte of zo voor vanille C/C++ loopt.


Antwoord 4

Het probleem kan worden opgelost door CRT van msvcrtd.lib toe te voegen aan de linkerbibliotheek.
Omdat cryptlib.lib de CRT-versie van debug gebruikte.

Other episodes