Невідповідність, виявлена ​​для "RuntimeLibrary"


114

Я завантажив і видобув 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, нічого іншого. Я використовую Windows 7 64 біт, і сьогодні я завантажив VS C ++, тому це має бути найновіша версія.



1
Я встановив бібліотеку виконання мого проекту на багатопотокову налагодження (це була настройка, що використовується в crypto ++) і тепер вона компілюється! :) Дуже дякую.
Момонга

Проблеми виникли набагато раніше, коли ти бігав VCUpgrade. Ви бачите симптоми збою VCUpgrade, про який повідомили як про успіх .
jww

Відповіді:


233

(На це вже відповідають у коментарях, але оскільки на це немає фактичної відповіді , я пишу це.)

Ця проблема виникає в новіших версіях 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. Інструменти для в'язки попередження LNK4098 на MSDN
  2. / MD, / ML, / MT, / LD (Використовуйте бібліотеку часу виконання) на MSDN
  3. Помилки побудови з VC11 Beta - змішування ліній MTd з MDd exes не вдається зв’язатись на Bugzilla @ Mozilla

ОНОВЛЕННЯ : (Це у відповідь на коментар, який запитує причину, з якою потрібно насторожитися.)

Якщо два фрагменти коду, які ми пов'язуємо разом, самі пов'язують та використовують стандартну бібліотеку, то стандартна бібліотека повинна бути однаковою для обох, якщо не буде дуже обережно, як наші два фрагменти коду взаємодіють і передають дані. Взагалі, я б сказав, що майже для всіх ситуацій використовуйте точно таку ж версію стандартної версії бібліотеки (щодо налагодження / випуску, потоків і, очевидно, версії Visual C ++, серед іншого, як налагодження ітератора тощо).

Найважливіша частина проблеми полягає в наступному: мати однакове уявлення про розмір об'єктів по обидва боки виклику функції .

Розглянемо, наприклад, що названі вище фрагменти коду називаються Aі B. A складено проти однієї версії стандартної бібліотеки, а B проти іншої. На думку А, якийсь випадковий об'єкт, який стандартна функція повертає до нього (наприклад, блок пам'яті, ітератор, FILEоб'єкт або будь-який інший), має певний розмір і макет (пам'ятайте, що компонування структури визначається і фіксується під час компіляції в C / C ++.) З будь-якої з кількох причин уявлення Б про розмір / компонування одних і тих же об'єктів відрізняється (це може бути через додаткову інформацію про налагодження, природну еволюцію структур даних з часом тощо).

Тепер, якщо A викликає стандартну бібліотеку і повертає об'єкт назад, потім передає цей об'єкт B, і B будь-яким чином торкається цього об'єкта, ймовірність полягає в тому, що B зіпсує цей об’єкт вгору (наприклад, запише неправильне поле або минулий кінець про неї тощо)

Сказане не є єдиним видом проблем, які можуть трапитися. Внутрішні глобальні або статичні об'єкти в стандартній бібліотеці також можуть спричинити проблеми. І є і більш незрозумілі класи проблем.

Все це стає більш привабливим у деяких аспектах при використанні DLL (динамічна бібліотека виконання) замість libs (статична бібліотека часу виконання).

Ця ситуація може стосуватися будь-якої бібліотеки, яка використовується двома фрагментами коду, які працюють разом, але стандартна бібліотека використовує більшість (якщо не майже всі) програм, і це збільшує шанси на зіткнення.

Те, що я описав, - це, очевидно, полита та спрощена версія фактичного безладу, який чекає вас, якщо ви змішаєте бібліотечні версії. Я сподіваюся, що це дає вам уявлення про те, чому ви не повинні цього робити!


Я трохи розгублений. Помилка OP - LNK2038 . Оскільки це відбувається не з усіма контурами, я підозрюю, що криптовалюта ++ переслідує деякі параметри CRT, які унеможливлюють змішування смаків CRT - зазвичай це лише попередження (LNK4098), і ви можете бути в безпеці, якщо знаєте, що ви робите (не рекомендується, але можливо з обмеженнями, див., наприклад, stackoverflow.com/a/19944935/948581 ). Я не знаю, чому Crypto ++ впливає таким чином.

1
@Tibo: це не імпорт бібліотек для DLL; Я вважаю, що Crypto ++ насправді статично пов'язаний з програмою. Це означає, що будь-яка невідповідність стандартної бібліотеки, пов'язана з одним модулем проти іншого (ймовірно), порушує "Правило одного визначення". Що погано. Це раніше не було помилкою, оскільки лінкер навіть не зміг виявити це (назви функцій / типів були однакові, але їх тіла та визначення суттєво відрізнялися) до VC10, коли лінкер / бібліотекар почав "тегувати" модулі він видав додаткову інформацію про конфігурацію збірки ...
yzt

@Tibo: ... (продовження з попереднього коментаря) Наприклад, подивіться перший блок помилок, про який повідомляє ОП. Там " RuntimeLibrary " - це тег як для бібліотеки Crypto ++, так і для об'єктного файлу програми ОП, а його значення - " MDd_DynamicDebug " для одного з них та " MTd_StaticDebug " для іншого. Таким чином, лінкер, який намагається з'єднати два об'єктні файли разом, може виявити і повідомити про цілий новий клас помилок, враховуючи, що лінкери, які створили ці об’єктні файли, позначають їх будь-якою відповідною інформацією, зокрема будь-якими налаштуваннями, які потенційно можуть порушити ODR.
yzt

Хоча я цілком погоджуюся з вами, тут все ще є область таємниці. Що стосується проблеми ОП, я думаю, що він включає "dll.h" з Crypto ++, а потім намагається встановити зв'язок зі статичною лібкою замість бібліотеки імпорту DLL. Але я бачив такі самі помилки на одному комп’ютері, а не на іншому (VS2013 ultimate sp4 -> помилка, VS2013 спільнота sp5 -> ок) ...

1
@yzt Я вирішив рішення. Замість використання swicth / ZW, Windows пропонує спосіб використання API WinRT через COM, використовуючи обгортку під назвою WRL. Просто не використання / ZW ускладнює кодування мало, оскільки він приховує деталі реалізації COM, але WinRT можна використовувати без / ZW.
Сахіл Сінгх

3

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

Перетворення, ймовірно, не було успішним. Єдине, що було успішним, це запуск VCUpgrade. Фактична сама конверсія не вдалася, але ви не знаєте, поки не відчуєте помилки, які ви бачите. Деякі деталі див. У візуальній студії на вікі Crypto ++.


Будь-які ідеї, як це виправити?

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


vs2010.zip, vs2010-dynamic.zipі vs2005-dynamic.zipбудуються з останніх джерел GitHub . Станом на це написання (1 червня 2016 р.), Це фактично попередньо 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 ++.


Я слідував інструкціям у wiki cryptopp, завантажив vs2010-dynamic.zip і вставив його вміст у код cryptopp563. Вбудовано та не вистачає деяких вихідних файлів. У Вікі немає проблем, зазначаючи, що поштовий індекс призначений для останнього проекту на github, і просто видаліть усі відсутні файли. Видалено. Тепер проект просто не будує: 4 помилки посилань, один приклад: помилка LNK2001: невирішений зовнішній символ "void __cdecl OutputResultOperations (char const *, char const *, bool, без підписання, подвійний)" (? OutputResultOperations @@ YAXPBD0_NKN @ З)
Янів

Виявилося, що було відсутнє у проекті bench.cpp. Але навіть після цього він не компілювався, поки я не застосував це виправлення до fiptest.cpp github.com/weidai11/cryptopp/pull/151/files?diff=split Я б хотів, щоб вони навели певний порядок у цьому, наприклад додайте поштові файли проекту. в git чи щось таке. І так, я знехтував сказати, що мій компілятор - це оновлення VS2015 2. Підсумок, дотримуйтесь підказок, які я написав, і це працює.
Янів

@Yaniv - Перший коментар, що ви рекомендуєте, щоб інші користувачі не відчували проблем? Для другого коментаря ми плануємо взяти пластир, як тільки ми його повністю перевіримо. Чи можемо ми тим часом щось зробити? (Я додав додаткову інформацію до цієї відповіді, але хочу переконатися, що у користувачів не виникне проблем).
jww

По-перше, велике спасибі за це. Криптовалюта ++ насправді гойдає. Щодо проблем зі збіркою, спробуйте зберегти вікна sln та файли проектів сумісними з останніми файлами в проекті, і оскільки ці зміни, звичайно, ці збірки вікон повинні бути якимось чином пов’язані з кодовою базою даних, а може бути і з вихідним деревом. Якщо це занадто багато, принаймні переконайтеся, що поштовий файл із середовищем побудови візуальної студії сумісний з поточним стабільним офіційним випуском.
Янів

Що стосується патча для fiptest.cpp - він, здається, є дещо іншим щодо VS2015, тому, мабуть, кожен, хто бажає використовувати VS2015, повинен застосувати цей патч. Це просто інший випадок в блоці #ifdef, який, здається, визначає правильний зворотний виклик налагодження для VS2015, і це дійсно легко виправити вручну.
Янів

3

У мене була ця проблема разом із невідповідністю в ITERATOR_DEBUG_LEVEL. Оскільки проблема неділі та вечора, здавалося, гаразд і добре піти, мене на деякий час гасили. Працюючи в ID VS2017 IDE (Провідник рішень), я нещодавно додав / скопіював посилання на вихідний файл до свого проекту (перетягнути ctrl) з іншого проекту. Розглядаючи властивості-> C / C ++ / Preprocessor - на рівні вихідного файлу, а не на рівні проекту - я помітив, що в конфігурації випуску для цього вихідного файлу було вказано _DEBUG замість NDEBUG. Яка була вся зміна, необхідна для позбавлення від проблеми.


1

Проблему можна вирішити, додавши CRT msvcrtd.lib у бібліотеку лінкерів. Оскільки cryptlib.lib використовував CRT-версію налагодження.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.