Wykryto niedopasowanie do "RuntimeLibrary"

Pobrałem i wyodrębniłem Crypto++ w C:\cryptopp. Wykorzystałem Visual Studio Express 2012 do zbudowania wszystkich projektów wewnątrz (zgodnie z Instrukcją w readme) i wszystko zostało zbudowane pomyślnie. Następnie zrobiłem projekt testowy w innym folderze i dodałem cryptolib jako zależność. Następnie dodałem ścieżkę include, dzięki czemu mogę łatwo dołączyć wszystkie nagłówki. Kiedy próbowałem skompilować, dostałem błąd dotyczący nierozwiązanych symboli.

Aby temu zaradzić, dodałem C:\cryptopp\Win32\Output\Debug\cryptlib.lib do linku dodatkowe zależności. Teraz dostaję ten błąd:

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

Dostaję też:

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

Kod, który próbowałem skompilować, był prosty (dostałem to z innej strony):

#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;
}
Jakieś pomysły, jak to naprawić? Naprawdę potrzebuję teraz tylko SHA-256, nic więcej. Używam Windows 7 64 bit, i pobrałem VS c++ dzisiaj, więc powinna być najnowsza wersja.
Author: jww, 2013-02-05

4 answers

(to jest już odpowiedź w komentarzach, ale ponieważ brakuje w nim rzeczywistej odpowiedzi , piszę to.)

Ten problem pojawia się w nowszych wersjach Visual C++ (starsze wersje zwykle po prostu po cichu łączyły program i ulegał awarii i wypaleniu w czasie uruchamiania.) Oznacza to, że niektóre biblioteki, które łączysz z programem (lub nawet niektóre pliki źródłowe wewnątrz samego programu) są przy użyciu różnych wersji CRT (środowiska uruchomieniowego C biblioteka.)

Aby naprawić ten błąd, musisz przejść do Project Properties (i/lub bibliotek, których używasz), następnie do C/C++, następnie Code Generation i sprawdzić wartość Runtime Library; powinno to być dokładnie takie samo dla wszystkich plików i bibliotek, które łączysz. (Zasady są trochę bardziej zrelaksowane w linkowaniu z bibliotekami DLL, ale nie zamierzam wchodzić w "dlaczego" i więcej szczegółów tutaj.)

Obecnie istnieją cztery opcje tego ustawienie:

  1. Debugowanie Wielowątkowe
  2. wielowątkowy debuger DLL
  3. Wydanie Wielowątkowe
  4. wielowątkowa biblioteka DLL

Twój szczególny problem wydaje się wynikać z połączenia biblioteki zbudowanej z "multithreaded Debug" (tj. statyczny wielowątkowy debuger CRT) z programem, który jest budowany przy użyciu ustawienia" Multithreaded Debug DLL " (tj. dynamiczny wielowątkowy debuger CRT.) Należy zmienić to ustawienie albo w bibliotece, albo w twoim programie. Na razie proponuję zmienić to w programie.

Zauważ, że ponieważ Projekty Visual Studio używają różnych zestawów ustawień projektu do debugowania i wydania kompilacji (i 32/64-bitowych kompilacji), powinieneś upewnić się, że ustawienia te pasują do wszystkich tych konfiguracji projektu.

Aby uzyskać (niektóre) więcej informacji, możesz zobaczyć te (link z komentarza powyżej):

  1. Linker Tools Warning LNK4098 on MSDN
  2. / MD, / ML, / MT, / LD (użycie Biblioteka Run-Time) na MSDN
  3. W związku z tym, że nie jest to możliwe, nie jest to możliwe, ponieważ nie jest to możliwe.]}

UPDATE: (jest to odpowiedź na komentarz, który prosi o powód, dla którego należy zachować taką ostrożność.)

Jeśli dwa fragmenty kodu, które ze sobą łączymy, łączą się z biblioteką standardową i używają jej, to biblioteka standardowa musi być taka sama dla obu z nich, chyba że great care jest o tym, jak nasze dwa elementy kodu współdziałają i przekazują dane. Ogólnie rzecz biorąc, powiedziałbym, że dla prawie wszystkich sytuacji wystarczy użyć dokładnie tej samej wersji środowiska uruchomieniowego biblioteki standardowej (odnośnie debugowania/wydania, wątków i oczywiście wersji Visual C++, między innymi debugowania iteratora itp.)

Najważniejszą częścią problemu jest to: posiadanie tego samego pojęcia o wielkości obiektów po obu stronach wywołania funkcji .

Rozważmy na przykład że powyższe dwa fragmenty kodu nazywa się A i B. A jest skompilowane przeciwko jednej wersji biblioteki standardowej, A B przeciwko innej. W widoku a, jakiś losowy obiekt, który zwraca do niego standardowa funkcja (np. blok pamięci, iterator, obiekt FILE lub cokolwiek innego) ma określony rozmiar i układ (pamiętaj, że układ struktury jest ustalany i ustalany podczas kompilacji w C / C++.) Z kilku powodów, idea rozmiaru/układu tych samych obiektów jest Inne (może to wynikać z dodatkowych informacji o debugowaniu, naturalnej ewolucji struktur danych w czasie, itp.)

Teraz, jeśli a wywoła bibliotekę standardową i pobiera obiekt z powrotem, następnie przekazuje ten obiekt do B, A B dotyka go w jakikolwiek sposób, jest szansa, że B zepsuje ten obiekt (np. napisze złe pole lub przejdzie za jego koniec, itd.)

Powyższe nie jest jedynym rodzajem problemów, które mogą się zdarzyć. Wewnętrzne obiekty globalne lub statyczne w bibliotece standardowej mogą powodować problemy też. Są też bardziej niejasne klasy problemów.

Wszystko to staje się dziwniejsze w niektórych aspektach, gdy używa bibliotek DLL (dynamic runtime library) zamiast libs (static runtime library.)

Ta sytuacja może dotyczyć każdej biblioteki używanej przez dwa kawałki kodu, które współpracują ze sobą, ale biblioteka standardowa jest używana przez większość (jeśli nie prawie wszystkie) programów, co zwiększa szanse na kolizję.

To, co opisałem, jest oczywiście rozwodnione i uproszczone wersja rzeczywistego bałaganu, który czeka na Ciebie, jeśli wymieszasz wersje biblioteki. Mam nadzieję, że daje Ci to pojęcie, dlaczego nie powinieneś tego robić!

 244
Author: yzt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-17 12:54:53

Pobrałem i wyodrębniłem Crypto++ w C:\cryptopp. Wykorzystałem Visual Studio Express 2012 do zbudowania wszystkich projektów wewnątrz (zgodnie z Instrukcją w readme) i wszystko zostało zbudowane pomyślnie. Następnie zrobiłem projekt testowy w innym folderze i dodałem cryptolib jako zależność.

Konwersja prawdopodobnie nie powiodła się. Jedyną rzeczą, która odniosła sukces, było uruchomienie VCUpgrade. Sama rzeczywista konwersja nie powiodła się, ale nie wiesz, dopóki nie doświadczysz błędy, które widzisz. Aby uzyskać więcej informacji, zobacz Visual Studio na wiki Crypto++.


Jakieś pomysły, jak to naprawić?

Aby rozwiązać swoje problemy, należy pobrać vs2010.zip jeśli chcesz statyczne C / C++ Runtime linking (/MT lub /MTd), lub vs2010-dynamic.zip jeśli chcesz dynamicznie łączyć środowisko uruchomieniowe C / C++ (/MT lub /MTd). Oba naprawiają utajone, ciche awarie produkowane przez VCUpgrade.


vs2010.zip, vs2010-dynamic.zip oraz vs2005-dynamic.zip są zbudowane z najnowszych źródeł GitHub. W momencie pisania tego tekstu (JUN 1 2016), jest to skutecznie pre-Crypto++ 5.6.4. Jeśli używasz plików ZIP z niższym poziomem Crypto++, takim jak 5.6.2 lub 5.6.3, napotkasz drobne problemy.

Zdaję sobie sprawę z dwóch drobnych problemów. Pierwsza to zmiana nazwy bench.cpp na bench1.cpp. Jego błąd jest albo:

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

Poprawką jest albo (1) Otwórz cryptest.vcxproj w notatnik, Znajdź bench1.cpp, a następnie zmień jego nazwę na bench.cpp. Lub (2) zmienić nazwę bench.cpp na bench1.cpp w systemie plików. Proszę nie usuwać tego pliku.

Drugi problem jest nieco trudniejszy, ponieważ jest ruchomym celem. W niższych wersjach, takich jak 5.6.2 lub 5.6.3, brakuje najnowszych klas dostępnych w GitHub . Brakujące pliki klas obejmują HKDF( 5.6.3), RDRAND (5.6.3), RDSEED (5.6.3), ChaCha (5.6.4), BLAKE2 (5.6.4), Poly1305 (5.6.4), itd.

Poprawką jest usunięcie brakujących pliki źródłowe z plików projektu Visual Studio, ponieważ nie istnieją dla wersji down level.

Inną opcją jest dodanie brakujących plików klas z najnowszych źródeł, ale mogą wystąpić komplikacje. Na przykład, wiele źródeł subtelnie zależy od najnowszych config.h, cpu.h i cpu.cpp. "Subtelność" polega na tym, że nie zdasz sobie sprawy, że dostajesz lekcję niedostatecznie wykonującą.

Przykładem klasy niedostatecznie wykonującej jest BLAKE2. config.h dodaje czas kompilacji ARM-32 i ARM-64 wykrywanie. cpu.h i cpu.cpp dodaje detekcję instrukcji runtime ARM, która zależy od detekcji czasu kompilacji. Jeśli dodasz BLAKE2 bez innych plików, to żaden z nich nie zostanie wykryty i otrzymasz prostą implementację C / C++. Prawdopodobnie nie zdasz sobie sprawy, że brakuje Ci okazji neonowej, która biegnie wokół 9 do 12 cykli na bajt w porównaniu do 40 cykli na bajt lub tak dla vanilla C / C++.

 3
Author: jww,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-01 04:03:58

Miałem ten problem wraz z niedopasowaniem w ITERATOR_DEBUG_LEVEL. Ponieważ problem z niedzielnym wieczorem wydawał się w porządku i gotowy do pracy, zostałem wystawiony na jakiś czas. Pracując w De VS2017 IDE (Solution Explorer) niedawno dodałem / skopiowałem odniesienie do pliku źródłowego do mojego projektu (Ctrl-drag) z innego projektu. Patrząc na właściwości - > C / C++ / preprocesor - na poziomie pliku źródłowego, a nie na poziomie projektu - zauważyłem, że w konfiguracji Wydania zamiast NDEBUG podano dla tego plik źródłowy. To była cała zmiana potrzebna do pozbycia się problemu.

 3
Author: Jan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-22 19:03:34

Problem można rozwiązać dodając CRT z msvcrtd.lib w bibliotece linker. Ponieważ cryptlib.lib użyła wersji CRT debugowania.

 1
Author: abhijithkp,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-06-20 09:30:50