Несоответствие обнаружено для '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 версию отладки.