Несоответствие обнаружено для 'RuntimeLibrary'
Я загрузил и извлек Crypto ++ в C:\cryptopp. Я использовал Visual Studio Express 2012 для создания всех проектов внутри (как указано в readme), и все было успешно построено. Затем я сделал тестовый проект в другой папке и добавил криптолиб в качестве зависимости. После этого я добавил путь включения, чтобы я мог легко включать все заголовки. Когда я попытался скомпилировать, у меня возникла ошибка в отношении неразрешенных символов.
Чтобы исправить это, я добавил C:\cryptopp\Win32\Output\Debug\cryptlib.lib
, чтобы связать дополнительные зависимости. Теперь я получаю эту ошибку:
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
Я также получаю:
Error 12 error LNK2005: "public: __thiscall std::_Container_base12::_Container_base12(void)" ([email protected]@@[email protected]) 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)" ([email protected]@@[email protected]) 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)" ([email protected][email protected]@@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)" ([email protected]@[email protected]@[email protected]@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
Код, который я пытался скомпилировать, был прост (я получил это с другого сайта):
#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;
}
Есть идеи, как это исправить? Мне действительно нужен SHA-256 прямо сейчас, больше ничего.
Я использую 64-разрядную версию Windows 7, и сегодня я загрузил VS С++, поэтому она должна быть самой новой версией.
Ответы
Ответ 1
(об этом уже ответили в комментариях, но поскольку у него нет фактического ответа, я пишу это.)
Эта проблема возникает в более поздних версиях Visual С++ (более старые версии обычно просто молчали связаны с программой, и она будет разбиваться и записываться во время выполнения.) Это означает, что некоторые из библиотек, которые вы связываете с вашей программой (или даже некоторые исходных файлов внутри самой программы) используют разные версии CRT (библиотека C RunTime).
Чтобы исправить эту ошибку, вам нужно перейти в Project Properties
(и/или те библиотеки, которые вы используете), затем в C/C++
, затем Code Generation
и проверить значение Runtime Library
; это должно быть точно таким же для всех файлов и библиотек, которые вы связываете вместе. (Правила немного более расслаблены для связи с DLL, но я не буду вдаваться в "почему" и более подробно здесь.)
В настоящее время существует четыре параметра для этого параметра:
- Многопоточная отладка
- Многопоточная отладка DLL
- Многопоточный выпуск
- Многопоточная версия DLL
Ваша конкретная проблема, по-видимому, связана с тем, что вы связываете библиотеку, созданную с помощью "многопотоковой отладки" (то есть статический многопотоковый отладчик CRT), против программы, которая создается с использованием параметра "Многопоточная отладка DLL" (то есть динамического многопоточного отладочного CRT). Вы должны изменить этот параметр либо в библиотеке, либо в своей программе. На данный момент я предлагаю изменить это в вашей программе.
Обратите внимание, что, поскольку проекты Visual Studio используют разные наборы параметров проекта для отладочных и релизных сборок (и 32/64-разрядных построений), вы должны убедиться, что параметры совпадают во всех этих конфигурациях проекта.
Для (некоторых) дополнительной информации вы можете увидеть их (связанные с комментарием выше):
UPDATE: (Это в ответ на комментарий, в котором говорится о причине, что это необходимо сделать.)
Если два фрагмента кода, которые мы связываем вместе, сами связаны с стандартной библиотекой и используют ее, то стандартная библиотека должна быть одинаковой для обеих из них, если не будет особо осторожно относиться к тому, как наши два фрагмента кода взаимодействуют и проходят вокруг данных. Как правило, я бы сказал, что почти во всех ситуациях просто используйте ту же самую версию стандартной среды исполнения библиотеки (относительно отладки/выпуска, потоков и, очевидно, версии Visual С++, среди прочего, таких как отладка итератора и т.д.)
Самая важная часть проблемы заключается в следующем: имея ту же идею о размере объектов по обе стороны вызова функции.
Рассмотрим, например, что эти две части кода называются A
и B
. A скомпилирован против одной версии стандартной библиотеки, а B - другой. В представлении A некоторый случайный объект, возвращаемый к нему стандартной функцией (например, блок памяти или итератор или объект FILE
или что-то еще), имеет определенный размер и макет (помните, что структура структуры определяется и фиксируется во время компиляции в C/С++.) По какой-либо из нескольких причин идея B/размер одного и того же объекта различна (это может быть связано с дополнительной информацией отладки, естественной эволюцией структур данных с течением времени и т.д.).
Теперь, если A вызывает стандартную библиотеку и возвращает объект обратно, то передает этот объект в B, и B каким-либо образом затрагивает этот объект, скорее всего, B будет помешать этому объекту (например, написать неправильное поле или мимо конца и т.д.)
Вышеупомянутые проблемы - это не единственные проблемы, которые могут случиться. Внутренние глобальные или статические объекты в стандартной библиотеке также могут вызвать проблемы. И есть еще более неясные классы проблем.
Все это становится более странным в некоторых аспектах при использовании DLL (динамической библиотеки времени выполнения) вместо libs (статическая библиотека времени выполнения).
Эта ситуация может применяться к любой библиотеке, используемой двумя фрагментами кода, которые работают вместе, но стандартная библиотека используется большинством (если не почти всеми) программами и увеличивает шансы столкновения.
То, что я описал, - это, очевидно, политая и упрощенная версия фактического беспорядка, который вас ждет, если вы смешиваете версии библиотеки. Я надеюсь, что это даст вам представление о том, почему вы не должны этого делать!
Ответ 2
Я загрузил и извлек Crypto ++ в C:\cryptopp. Я использовал Visual Studio Express 2012 для создания всех проектов внутри (как указано в readme), и все было успешно построено. Затем я сделал тестовый проект в другой папке и добавил криптолиб в качестве зависимости.
Конверсия, вероятно, не была успешной. Единственное, что было успешным, - это запуск VCUpgrade. Фактическое само преобразование потерпело неудачу, но вы не знаете, пока не испытаете ошибки, которые видите. Для некоторых деталей см. Visual Studio в вики Crypto ++.
Любые идеи, как это исправить?
Чтобы решить ваши проблемы, вы должны скачать vs2010.zip
, если вы хотите, чтобы статические ссылки на время выполнения C/С++ (/MT
или /MTd
), или vs2010-dynamic.zip
, если требуется динамическое связывание времени выполнения C/С++ (/MT
или /MTd
). Оба фиксируют скрытые, молчащие сбои, созданные VCUpgrade.
vs2010.zip
, vs2010-dynamic.zip
и vs2005-dynamic.zip
построены из последних источников GitHub. На момент написания этой статьи (JUN 1 2016), это эффективно pre-Crypto ++ 5.6.4. Если вы используете ZIP файлы с нижним уровнем Crypto ++, например, 5.6.2 или 5.6.3, тогда вы столкнетесь с незначительными проблемами.
Есть две незначительные проблемы, о которых я знаю. Сначала переименуйте bench.cpp
в bench1.cpp
. Его ошибка:
-
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)" ([email protected]@[email protected])
Исправление состоит в том, чтобы (1) открыть cryptest.vcxproj
в блокноте, найти bench1.cpp
, а затем переименовать его в bench.cpp
. Или (2) переименуйте bench.cpp
в bench1.cpp
в файловой системе. Не удаляйте этот файл.
Вторая проблема немного сложнее, потому что ее движущаяся цель. В версиях нижнего уровня, таких как 5.6.2 или 5.6.3, отсутствуют последние классы, доступные в GitHub. Недопустимые файлы классов включают HKDF (5.6.3), RDRAND (5.6.3), RDSEED (5.6.3), ChaCha (5.6.4), BLAKE2 (5.6.4), Poly1305 (5.6.4) и т.д.
Исправление состоит в том, чтобы удалить отсутствующие исходные файлы из файлов проекта Visual Studio, поскольку они не существуют для релизов нижнего уровня.
Другой вариант - добавить отсутствующие файлы классов из последних источников, но могут быть сложности. Например, многие источники изящно зависят от последних config.h
, cpu.h
и cpu.cpp
. "Тонкость" заключается в том, что вы не поймете, что получаете недостаточно эффективный класс.
Примером недоиспользуемого класса является BLAKE2. config.h
добавляет время компиляции ARM-32 и ARM-64. cpu.h
и cpu.cpp
добавляет обнаружение команд ARM во время выполнения, что зависит от обнаружения времени компиляции. Если вы добавите BLAKE2 без других файлов, то ни одно обнаружение не произойдет, и вы получите прямую реализацию C/С++. Вероятно, вы не поймете, что вам не хватает возможности NEON, которая работает от 9 до 12 циклов за байт против 40 циклов за байт или около того для ванильного C/С++.
Ответ 3
У меня была эта проблема вместе с несоответствием в ITERATOR_DEBUG_LEVEL. Поскольку проблема воскресного вечера, в конце концов, казалась нормальной и хорошей, я был потрясен на некоторое время. Работая в IDE de VS2017 (обозреватель решений), я недавно добавил/скопировал ссылку на исходный файл для моего проекта (Ctrl-drag) из другого проекта. Просматривая properties-> C/C++/Preprocessor - на уровне исходного файла, а не на уровне проекта - я заметил, что в конфигурации Release для этого исходного файла было указано _DEBUG вместо NDEBUG. Который был всем изменением, необходимым, чтобы избавиться от проблемы.
Ответ 4
Проблема может быть решена путем добавления CRT файла msvcrtd.lib в библиотеку линкера. Потому что cryptlib.lib использовал CRT версию отладки.