Обнаружено несоответствие для 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)" (??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

Код, который я пытался скомпилировать, был прост (я получил это с другого сайта):

#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 C ++, так что это должна быть самая новая версия.

90

Решение

(Это уже дано в комментариях, но так как ответ, Я пишу это.)

Эта проблема возникает в более новых версиях Visual C ++ (более старые версии обычно просто молча связывали программу, и она зависала и работала во время выполнения.) Это означает, что некоторые библиотеки, которые вы связываете с вашей программой (или даже некоторые исходные тексты) файлы внутри самой программы) используя разные версии CRT (библиотека C RunTime.)

Чтобы исправить эту ошибку, вам нужно зайти в свой Project Properties (и / или из библиотек, которые вы используете,) затем в C/C++, затем Code Generationи проверьте значение Runtime Library; это должно быть точно так же для все файлы и библиотеки, которые вы связываете вместе. (Правила немного более смягчены для связи с DLL, но я не буду вдаваться в «почему» и более подробно здесь.)

В настоящее время существует четыре варианта этого параметра:

  1. Многопоточная отладка
  2. Многопоточная отладочная DLL
  3. Многопоточный выпуск
  4. Многопоточная версия DLL

Ваша конкретная проблема, кажется, связана с тем, что вы связываете библиотеку, созданную с помощью «Многопоточной отладки» (то есть статической многопоточной отладки CRT), с программой, которая создается с помощью «Многопоточной отладки». DLL«настройка (то есть динамическая многопоточная отладка CRT.) Вам следует изменить эту настройку либо в библиотеке, либо в вашей программе. Сейчас я предлагаю изменить это в вашей программе.

Обратите внимание, что поскольку проекты Visual Studio используют разные наборы параметров проекта для сборок отладки и выпуска (и 32/64-разрядных сборок), вы должны убедиться, что параметры совпадают во всех этих конфигурациях проекта.

Для (некоторой) дополнительной информации, вы можете увидеть это (ссылка на комментарий выше):

  1. Инструменты Linker Предупреждение LNK4098 на MSDN
  2. / MD, / ML, / MT, / LD (использовать библиотеку времени выполнения) на MSDN
  3. Ошибки сборки с бета-версией VC11 — смешение библиотек MTd с exe-файлами MDd не удается связать на Bugzilla @ Mozilla

ОБНОВИТЬ: (Это является ответом на комментарий, в котором спрашивается причина, по которой следует проявлять такую ​​большую осторожность.)

Если два фрагмента кода, которые мы связываем вместе, сами ссылаются и используют стандартную библиотеку, то стандартная библиотека должна быть одинаковой для них обоих, если только отличный мы заботимся о том, как наши две части кода взаимодействуют и передают данные. Как правило, я бы сказал, что почти во всех ситуациях просто используйте одну и ту же версию стандартной среды выполнения библиотеки (в отношении отладки / выпуска, потоков и, очевидно, версии Visual C ++, среди прочего, таких как отладка итераторов и т. Д.)

Самая важная часть проблемы заключается в следующем: иметь одинаковое представление о размере объектов по обе стороны от вызова функции.

Рассмотрим, например, что два вышеуказанных фрагмента кода называются A а также B, А это скомпилированный против одной версии стандартной библиотеки, а B против другой. По мнению А, некоторый случайный объект, который ему возвращает стандартная функция (например, блок памяти, итератор или FILE объект или что-то еще) имеет некоторый определенный размер и расположение (помните, что структура структуры определяется и фиксируется во время компиляции в C / C ++.) По любой из нескольких причин представление B о размере / расположении одних и тех же объектов отличается (оно может из-за дополнительной отладочной информации, естественного развития структур данных с течением времени и т. д.)

Теперь, если A вызывает стандартную библиотеку и возвращает объект обратно, затем передает этот объект B, и B каким-либо образом касается этого объекта, есть вероятность, что B испортит этот объект (например, напишет неправильное поле или выйдет за конец). об этом и т. д.)

Вышесказанное — не единственный вид проблем, которые могут возникнуть. Внутренние глобальные или статические объекты в стандартной библиотеке также могут вызывать проблемы. И есть еще более неясные классы проблем.

Все это становится более странным в некоторых аспектах при использовании DLL (динамическая библиотека времени выполнения) вместо библиотек (статическая библиотека времени выполнения).

Эта ситуация может применяться к любой библиотеке, используемой двумя кусками кода, которые работают вместе, но стандартная библиотека используется большинством (если не почти всеми) программами, и это увеличивает шансы столкновения.

То, что я описал, — это, очевидно, упрощенная и упрощенная версия реального беспорядка, которая ждет вас, если вы смешаете версии библиотек. Я надеюсь, что это дает вам представление о том, почему вы не должны этого делать!

192

Другие решения

Я скачал и распаковал Crypto ++ в C: \ cryptopp. Я использовал Visual Studio Express 2012 для сборки всех проектов внутри (как указано в readme), и все было успешно построено. Затем я сделал тестовый проект в другой папке и добавил криптолиб в качестве зависимости.

Преобразование, вероятно, не было успешным. Единственное, что было успешным, это запуск VCUpgrade. Само преобразование не удалось, но вы не узнаете, пока не увидите ошибки, которые видите. Для некоторых деталей, см. Visual Studio на Crypto ++ вики.


Любые идеи, как это исправить?

Чтобы решить ваши проблемы, вы должны скачать vs2010.zip если вы хотите статическое связывание C / C ++ во время выполнения (/MT или же /MTd), или же vs2010-dynamic.zip если вы хотите динамическое связывание C / C ++ во время выполнения (/MT или же /MTd). Оба исправляют скрытые, тихие сбои, производимые VCUpgrade.


vs2010.zip, vs2010-dynamic.zip а также vs2005-dynamic.zip построены из последние источники GitHub. На момент написания статьи (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)" (?OutputResultOperations@@YAXPBD0_NKN@Z)

Исправление — либо (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 / C ++. Вы, вероятно, не поймете, что упускаете возможность NEON, которая работает от 9 до 12 циклов на байт против 40 циклов на байт или около того для ванильного C / C ++.

3

У меня была эта проблема вместе с несоответствием в ITERATOR_DEBUG_LEVEL.
Поскольку проблема воскресного вечера, в конце концов, казалась нормальной и хорошей, я был потрясен на некоторое время.
Работая в IDE de VS2017 (обозреватель решений), я недавно добавил / скопировал ссылку на исходный файл для моего проекта (Ctrl-drag) из другого проекта. Просмотр свойств-> C / C ++ / Препроцессор — на уровне исходного файла, а не на уровне проекта — Я заметил, что в конфигурации выпуска _DEBUG был указан вместо NDEBUG для этого исходного файла.
Который был всем изменением, необходимым, чтобы избавиться от проблемы.

2
По вопросам рекламы [email protected]