'RuntimeLibrary'에 대한 불일치 감지


114

C : \ cryptopp에서 Crypto ++를 다운로드하고 추출했습니다. 필자는 Visual Studio Express 2012를 사용하여 모든 프로젝트를 내부에서 빌드했고 (readme에서 지시 한대로) 모든 것이 성공적으로 빌드되었습니다. 그런 다음 다른 폴더에 테스트 프로젝트를 만들고 cryptolib를 종속성으로 추가했습니다. 그 후 모든 헤더를 쉽게 포함 할 수 있도록 포함 경로를 추가했습니다. 컴파일을 시도 할 때 해결되지 않은 기호에 대한 오류가 발생했습니다.

이를 해결하기 위해 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 ++에서 사용 된 설정)로 설정하고 이제 컴파일됩니다! :) 정말 고맙습니다.
Momonga 2013

실행했을 때 훨씬 일찍 문제가 발생했습니다 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. 링커 도구 경고 LNK4098MSDN의
  2. MSDN의 / MD, / ML, / MT, / LD (런타임 라이브러리 사용)
  3. VC11 베타에서 빌드 오류-MTd libs와 MDd exes를 혼합하면 Bugzilla @ Mozilla 에서 링크되지 않습니다.

UPDATE : (이렇게주의를 기울여야하는 이유를 묻는 댓글에 대한 답변입니다.)

우리가 함께 연결하는 자체에 연결하는 표준 라이브러리를 사용하여 해당 코드의 두 조각, 다음, 표준 라이브러리하지 않는 한, 둘 다에 대해 동일해야합니다 경우 주의를 우리의 두 개의 코드 조각은 상호 작용과 데이터를 주위에 전달하는 방법에 대해 취해진 다. 일반적으로 거의 모든 상황에서 표준 라이브러리 런타임의 똑같은 버전을 사용한다고 말하고 싶습니다 (디버그 / 릴리스, 스레드 및 분명히 Visual C ++ 버전과 관련하여 반복기 디버깅 등).

문제의 가장 중요한 부분은 이것이다 : 함수 호출의 양쪽에있는 객체의 크기에 대해 동일한 아이디어를 갖는 것 입니다.

예를 들어 위의 두 가지 코드가 Aand B. A는 표준 라이브러리의 한 버전에 대해 컴파일 되고 B는 다른 버전에 대해 컴파일 됩니다. A의 관점에서 표준 함수가 반환하는 임의의 객체 (예 : 메모리 블록, 반복기 또는 FILE객체 등)에는 특정 크기와 레이아웃이 있습니다 (구조 레이아웃은 C /에서 컴파일 타임에 결정되고 고정됨을 기억하십시오). C ++.) 여러 가지 이유로, 동일한 객체의 크기 / 레이아웃에 대한 B의 생각은 다릅니다 (추가 디버그 정보, 시간에 따른 데이터 구조의 자연스러운 진화 등으로 인해 발생할 수 있음).

이제 A가 표준 라이브러리를 호출하고 개체를 다시 가져온 다음 해당 개체를 B에 전달하고 B가 어떤 식 으로든 해당 개체에 닿으면 B가 해당 개체를 엉망으로 만들 가능성이 있습니다 (예 : 잘못된 필드를 작성하거나 끝을지나 그것의 등)

위의 문제가 발생할 수있는 유일한 문제는 아닙니다. 표준 라이브러리의 내부 전역 또는 정적 개체도 문제를 일으킬 수 있습니다. 그리고 더 모호한 문제도 있습니다.

libs (정적 런타임 라이브러리) 대신 DLL (동적 런타임 라이브러리)을 사용할 때이 모든 것이 일부 측면에서 더 이상해집니다.

이 상황은 함께 작동하는 두 개의 코드 조각에서 사용하는 모든 라이브러리에 적용될 수 있지만 표준 라이브러리는 대부분의 (거의 전부는 아니지만) 프로그램에서 사용되므로 충돌 가능성이 높아집니다.

내가 설명한 것은 분명히 라이브러리 버전을 혼합 할 때 당신을 기다리는 실제 혼란의 물이 적고 단순화 된 버전입니다. 나는 그것이 당신이 그것을하지 말아야하는 이유에 대한 아이디어를 제공하기를 바랍니다!


나는 약간 혼란 스럽습니다. OP의 오류LNK2038 입니다. 모든 라이브러리에서 발생하는 것은 아니기 때문에 CRT 풍미를 혼합하는 것을 불가능하게하는 일부 CRT 설정이있는 Crypto ++ 바이올린이 의심됩니다. 일반적으로 이는 경고 일뿐 (LNK4098)이며 수행하는 작업을 알고 있으면 안전 할 있습니다 (권장하지 않음, 제한적으로 가능합니다 . 예를 들어 stackoverflow.com/a/19944935/948581 참조 ). 그래도 Crypto ++가 이런 식으로 영향을받는 이유를 모르겠습니다.

1
@Tibo : DLL 용 가져 오기 라이브러리가 아닙니다. 저는 Crypto ++가 실제로 여기 프로그램과 정적으로 연결되어 있다고 믿습니다. 이는 한 모듈에서 다른 모듈과 연결되는 표준 라이브러리의 불일치 (아마도)가 "하나의 정의 규칙"을 위반 함을 의미합니다. 나쁘다. 링커 / 사서가 모듈에 "태그 지정"을 시작했을 때 VC10까지 링커가이를 감지 할 수 없었기 때문에 오류가 아니 었습니다 (함수 / 유형 이름은 같지만 본문과 정의가 크게 달랐습니다). 빌드 구성에 대한 추가 정보와 함께 생성되었습니다 ...
yzt

@Tibo : ... (이전 의견에서 계속됨) 예를 들어 OP가보고하는 첫 번째 오류 블록을 살펴보십시오. 여기에서 " RuntimeLibrary "는 Crypto ++ 라이브러리와 OP 프로그램의 개체 파일 모두에 대한 태그이며 그 값은 중 하나에 대해 " MDd_DynamicDebug "이고 다른 하나에 대해 " MTd_StaticDebug "입니다. 이러한 방식으로 두 개체 파일을 함께 연결하려는 링커는 해당 개체 파일을 생성 한 링커가 관련 정보, 특히 잠재적으로 ODR을 위반할 수있는 모든 설정으로 태그를 지정했기 때문에 완전히 새로운 오류 클래스를 감지하고보고 할 수 있습니다.
yzt 2015 년

나는 당신과 상당히 동의하지만 여기에는 여전히 신비한 영역이 있습니다. OP의 문제에 관해서는 그가 Crypto ++의 "dll.h"를 ​​포함시키고 DLL의 가져 오기 라이브러리 대신 정적 lib에 대한 링크를 시도합니다. 하지만 다른 컴퓨터가 아닌 한 컴퓨터에서 똑같은 오류를 보았습니다 (VS2013 ultimate sp4-> error, VS2013 community sp5-> ok) ...

1
@yzt 나는 해결책을 찾았습니다. / ZW swicth를 사용하는 대신 Windows는 WRL이라는 래퍼를 사용하여 COM을 통해 WinRT API를 사용하는 방법을 제공합니다. / ZW를 사용하지 않으면 COM 구현 세부 정보가 숨겨져 코딩이 조금 어렵지만 / ZW없이 WinRT를 사용할 수 있습니다.
사힐 싱

3

C : \ cryptopp에서 Crypto ++를 다운로드하고 추출했습니다. 필자는 Visual Studio Express 2012를 사용하여 모든 프로젝트를 내부에서 빌드했고 (readme에서 지시 한대로) 모든 것이 성공적으로 빌드되었습니다. 그런 다음 다른 폴더에 테스트 프로젝트를 만들고 cryptolib를 종속성으로 추가했습니다.

변환이 성공하지 못했을 것입니다. 성공한 유일한 것은 VCUpgrade의 실행이었습니다. 실제 변환 자체는 실패했지만 표시되는 오류가 발생할 때까지 알 수 없습니다. 일부 세부 정보 는 Crypto ++ 위키의 Visual Studio 를 참조하세요 .


이 문제를 해결하는 방법에 대한 아이디어가 있습니까?

문제를 해결하려면 vs2010.zip정적 C / C ++ 런타임 링크 ( /MT또는 /MTd)를 원하거나 vs2010-dynamic.zip동적 C / C ++ 런타임 링크 ( /MT또는 /MTd) 를 원할 경우 다운로드 해야합니다 . 둘 다 VCUpgrade에 의해 생성 된 잠재적이고 조용한 오류를 수정합니다.


vs2010.zip, vs2010-dynamic.zip그리고 최신 GitHub 소스vs2005-dynamic.zip 에서 빌드되었습니다 . 이 글을 쓰는 시점 (2016 년 6 월 1 일), 이는 사실상 Crypto ++ 5.6.4 이전 버전입니다. 5.6.2 또는 5.6.3과 같은 하위 수준 Crypto ++로 ZIP 파일을 사용하는 경우 사소한 문제가 발생합니다.

내가 알고있는 두 가지 사소한 문제가 있습니다. 첫 번째는 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.hcpu.cpp. "미묘함"은 당신이 성과가 저조한 수업을 받고 있다는 것을 깨닫지 못할 것입니다.

실적이 저조한 클래스의 예는 BLAKE2입니다. config.h컴파일 시간 ARM-32 및 ARM-64 감지를 추가합니다. cpu.hcpu.cpp컴파일 시간 감지에 따라 달라 런타임 ARM 명령어 감지 기능을 추가합니다. 다른 파일없이 BLAKE2를 추가하면 탐지가 발생하지 않고 곧바로 C / C ++ 구현이됩니다. 바닐라 C / C ++의 경우 바이트 당 40 사이클 정도에 비해 바이트 당 9-12 사이클 정도 실행되는 NEON 기회를 놓치고 있다는 사실을 깨닫지 못할 것입니다.


나는 cryptopp 위키의 지시에 따라 vs2010-dynamic.zip을 다운로드하고 그 내용을 cryptopp563 코드에 붙여 넣었습니다. 빌드되고 일부 소스 파일이 누락되었습니다. 위키는 zip이 github의 최신 프로젝트 용이라고 말하고 누락 된 파일을 삭제하면됩니다. 삭제 이제 프로젝트는 빌드하지 않습니다. 링크 오류 4 개, 예 : 오류 LNK2001 : 해결되지 않은 외부 기호 "void __cdecl OutputResultOperations (char const *, char const *, bool, unsigned long, double)"(? OutputResultOperations @@ YAXPBD0_NKN @ Z)
Yaniv

프로젝트에서 누락 된 bench.cpp가있는 것으로 밝혀졌습니다. 하지만 그 후에도이 수정 사항을 fiptest.cpp github.com/weidai11/cryptopp/pull/151/files?diff=split에 적용 할 때까지 컴파일되지 않았습니다 . 프로젝트 zip 파일을 추가하는 것과 같은 순서를 만들었 으면합니다. 자식이나 뭔가에. 그리고 예, 내 컴파일러가 VS2015 업데이트 2라고 말하는 것을 무시했습니다. 결론은 내가 작성한 힌트를 따르고 작동합니다.
Yaniv

@Yaniv-첫 번째 의견으로 다른 사용자가 문제를 겪지 않도록 무엇을 권장합니까? 두 번째 의견으로는 완전히 테스트를 마치면 패치를 적용 할 계획입니다. 그동안 우리가 할 수있는 일이 있습니까? (이 답변에 추가 정보를 추가했지만 사용자가 문제가 없는지 확인하고 싶습니다).
jww

첫째, 이렇게 해주셔서 감사합니다. Crypto ++는 정말 멋집니다. 빌드 문제와 관련하여 Windows sln 및 프로젝트 파일을 프로젝트의 최신 파일과 호환되도록 유지하십시오. 물론 이러한 변경 사항이 있으므로 이러한 Windows 빌드는 코드베이스에 연결되어야하며 소스 트리에있을 수도 있습니다. 너무 많으면 적어도 Visual Studio 빌드 환경의 zip 파일이 현재의 안정적인 공식 릴리스와 호환되는지 확인하십시오.
Yaniv

fiptest.cpp 패치와 관련하여-VS2015와는 다른 것처럼 보이므로 VS2015를 사용하려는 사람은이 패치를 적용해야합니다. VS2015에 대한 올바른 디버그 콜백을 정의하는 것처럼 보이는 #ifdef 블록의 또 다른 경우이며 수동으로 패치하는 것은 정말 쉽습니다.
Yaniv

3

ITERATOR_DEBUG_LEVEL의 불일치와 함께이 문제가 발생했습니다. 결국 일요일 저녁 문제가 괜찮아 보이고 좋은 것 같았 기 때문에 나는 한동안 밖으로 나갔다. VS2017 IDE (솔루션 탐색기)에서 작업하기 최근에 다른 프로젝트에서 내 프로젝트에 대한 소스 파일 참조를 추가 / 복사했습니다 (ctrl-drag). 프로젝트 수준이 아닌 소스 파일 수준에서 속성-> C / C ++ / 전처리기를 살펴보면 릴리스 구성에서이 소스 파일에 대해 NDEBUG 대신 _DEBUG가 지정되었음을 알았습니다. 문제를 해결하는 데 필요한 모든 변화였습니다.


1

링커 라이브러리에 msvcrtd.lib의 CRT를 추가하여 문제를 해결할 수 있습니다. cryptlib.lib는 CRT 버전의 디버그를 사용했기 때문입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.