检测到“ RuntimeLibrary”不匹配


114

我在C:\ cryptopp中下载并提取了Crypto ++。我使用Visual Studio Express 2012构建了内部的所有项目(如自述文件中所述),并且一切均已成功构建。然后,我在其他文件夹中创建了一个测试项目,并添加了cryptolib作为依赖项。之后,我添加了include路径,以便可以轻松包含所有标头。尝试编译时,出现有关未解析符号的错误。

为了解决这个问题,我添加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

当您跑步时,问题早就发生了VCUpgrade。您正在看到VCUpgrade失败的症状,并已报告为成功
jww

Answers:


233

(这已经在评论中得到了回答,但是由于它没有实际的答案,因此我正在写这篇文章。)

在新版本的Visual C ++中会出现此问题(旧版本通常只是默默地链接程序,并且它会在运行时崩溃并刻录。)这意味着您正在与程序链接的某些库(甚至是某些源代码)程序本身内部的文件)正在使用不同版本的CRT(C运行时库)。

要更正此错误,您需要进入Project Properties(和/或正在使用的那些库),然后进入C/C++,然后Code Generation,然后检查Runtime Library; 的值。对于要链接在一起的所有文件和库,这应该完全相同。(对于与DLL的链接,规则稍微宽松一些,但是在这里我不打算讨论“为什么”和更多细节。)

此设置当前有四个选项:

  1. 多线程调试
  2. 多线程调试DLL
  3. 多线程发布
  4. 多线程发布DLL

您的特定问题似乎源于将“多线程调试”(即静态多线程调试CRT)构建的库与使用“多线程调试DLL ”设置(即动态多线程调试CRT)构建的程序链接在一起的原因。库或程序中的此设置。现在,建议您在程序中更改此设置。

请注意,由于Visual Studio项目将不同的项目设置集用于调试和发布版本(以及32/64位版本),因此应确保这些设置在所有这些项目配置中均匹配。

有关(某些)更多信息,您可以查看以下内容(从上面的评论链接):

  1. MSDN上的链接器工具警告LNK4098
  2. MSDN上的/ MD,/ ML,/ MT,/ LD(使用运行时库)
  3. VC11 Beta生成错误-将MTd库与MDd exe混合使用时,无法在Bugzilla @ Mozilla上链接

更新:(这是对评论的回应,该评论要求必须非常谨慎。)

如果我们链接在一起的两段代码本身是针对标准库的链接并使用标准库,那么除非它们非常小心我们的两段代码如何交互和传递数据,否则两者的标准库必须相同。通常,我想说的是,几乎在所有情况下都使用与标准库运行时完全相同的版本(关于调试/发行版,线程,显然还有Visual C ++的版本,以及诸如迭代器调试等)。

问题的最重要部分是:对函数调用的任一侧的对象大小有相同的想法

例如考虑上面的代码两片被称为AB。A是针对标准库的一个版本编译的,而B是针对标准库的一个版本编译的。在A的观点中,标准函数返回给它的某个随机对象(例如,内存块,迭代器或FILE对象等)具有某些特定的大小和布局(请记住,结构布局是在C //编译时确定并固定的)由于某些原因,B对同一对象的大小/布局的想法是不同的(可能是由于附加的调试信息,数据结构随时间的自然演变等)。

现在,如果A调用标准库并取回一个对象,然后将该对象传递给B,并且B以任何方式触摸该对象,则B很有可能会弄乱该对象(例如,写错字段或超出结尾)等等)

以上并不是唯一可能发生的问题。标准库中的内部全局或静态对象也会引起问题。而且还有更多晦涩难懂的问题。

在使用DLL(动态运行时库)而不是lib(静态运行时库)时,所有这些在某些方面都变得很奇怪。

这种情况可以适用于两个可以协同工作的代码所使用的任何库,但是大多数(即使不是几乎所有)程序都使用标准库,这增加了发生冲突的机会。

我所描述的显然是对实际混乱情况的简化和简化版本,如果您混合使用库版本,则会等待您。我希望它能使您了解为什么不应该这样做!


我有点困惑。OP的错误LNK2038。由于并非所有的lib都发生这种情况,我怀疑Crypto ++摆弄了一些CRT设置,使其无法混合CRT口味-通常这只是一个警告(LNK4098),如果您知道自己的操作,则可能会很安全(不建议这样做,但可能有限制,请参见例如stackoverflow.com/a/19944935/948581)。不过,我不知道为什么Crypto ++会受到这种影响。

1
@Tibo:这些不是DLL的导入库;我相信Crypto ++实际上是在这里与程序静态链接的。这意味着在一个模块中链接到另一个模块的标准库中的任何不匹配(可能)都违反了“一个定义规则”。不好 以前这不是错误,因为链接器甚至无法检测到错误(功能/类型名称相同,但是它们的主体和定义明显不同),直到VC10链接器/库管理员开始“标记”模块时为止它产生了有关构建配置的额外信息...
yzt

@Tibo:...(续上一条注释)例如,查看OP正在报告的第一个错误块。在那里,“ RuntimeLibrary ”是Crypto ++库和OP程序的目标文件上的标记,其中一个的值为“ MDd_DynamicDebug ”,另一个为“ MTd_StaticDebug ”。这样,尝试将两个目标文件链接在一起的链接器可以检测并报告全新的错误类别,前提是生成这些目标文件的链接器会使用任何相关信息来标记它们,尤其是可能违反ODR的任何设置。
yzt

尽管我非常同意您的意见,但这里仍然有一个谜。至于OP的问题,我想他正在包含Crypto ++的“ dll.h”,然后尝试链接到静态库而不是DLL的导入库。但是我已经在一台计算机上看到了完全相同的错误,而不是另一台计算机上(VS2013 Ultimate sp4->错误,VS2013 community sp5-> OK)...

1
@yzt我想出了一个解决方案。Windows提供了一种使用称为WRL的包装程序通过COM使用WinRT API的方法,而不是使用/ ZW swicth。只是不使用/ ZW会使编码变得有点困难,因为它隐藏了COM实现细节,但是可以在不使用/ ZW的情况下使用WinRT。
萨希尔·辛格

3

我在C:\ cryptopp中下载并提取了Crypto ++。我使用Visual Studio Express 2012来构建内部的所有项目(如自述文件中所述),并且一切均已成功构建。然后,我在其他文件夹中创建了一个测试项目,并添加了cryptolib作为依赖项。

转换可能不成功。唯一成功的是VCUpgrade的运行。实际的转换本身失败了,但是直到遇到错误,您才知道。有关某些详细信息,请参见Crypto ++ Wiki上的Visual Studio


任何想法如何解决这一问题?

要解决您的问题,vs2010.zip如果要进行静态C / C ++运行时链接(/MT/MTd),或者vs2010-dynamic.zip要进行动态C / C ++运行时链接(/MT/MTd),则应下载。两者都修复了VCUpgrade产生的潜在的,无提示的故障。


vs2010.zipvs2010-dynamic.zipvs2005-dynamic.zip根据最新的GitHub来源构建。在撰写本文时(2016年6月1日),该版本实际上是Crypto ++ 5.6.4之前的版本。如果您使用的是Zrypto文件,其Crypto ++版本较低,例如5.6.2或5.6.3,则将遇到一些小问题。

我知道有两个小问题。首先是重命名bench.cppbench1.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.cppbench1.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.hcpu.hcpu.cpp。“微妙”是您不会意识到自己的学习成绩不佳。

表现不佳的类的一个示例是BLAKE2。config.h添加了编译时ARM-32和ARM-64检测。cpu.hcpu.cpp添加了运行时ARM指令检测,这取决于编译时间检测。如果添加BLAKE2而没有其他文件,则不会进行任何检测,并且可以直接获得C / C ++实现。您可能不会意识到您会错过NEON机会,NEON机会每字节大约运行9到12个周期,而普通C / C ++则大约每字节40个周期。


我按照cryptopp Wiki中的说明进行操作,下载了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文件变成git之类的东西。是的,我忽略了说我的编译器是VS2015 update2。最重要的是,按照我编写的提示进行工作。
亚尼夫

@Yaniv-对于第一个评论,您有何建议,以便其他用户不会遇到问题?对于第二条评论,我们计划在我们对补丁进行全面测试后再进行开发。同时,我们有什么可以做的?(我在此答案中添加了其他信息,但我想确保用户不会遇到麻烦)。
jww

首先,非常感谢您这样做。Crypto ++确实很糟糕。关于构建问题,请尝试使Windows sln和项目文件与项目中的最新文件兼容,并且由于这些更改,当然,这些Windows构建应该以某种方式链接到代码库,甚至可能位于源代码树上。如果太多,请至少确保带有Visual Studio构建环境的zip文件与当前稳定的正式版本兼容。
亚尼夫

关于fiptest.cpp的补丁-VS2015似乎有所不同,所以我想任何想使用VS2015的人都需要应用此补丁。#ifdef块中的另一种情况似乎为VS2015定义了正确的调试回调,并且手动修补真的很容易。
亚尼夫

3

我在ITERATOR_DEBUG_LEVEL中遇到不匹配的问题。毕竟,周日晚上的问题似乎还可以,很高兴,所以我被淘汰了一段时间。我最近在VS2017 IDE(解决方案资源管理器)中工作,我从另一个项目添加/复制了对我的项目(ctrl-drag)的源文件引用。在源文件级别而不是项目级别查看属性-> C / C ++ / Preprocessor- 我注意到在发布配置中为此源文件指定了_DEBUG而不是NDEBUG。这是解决问题所需的全部更改。


1

通过在链接器库中添加msvcrtd.lib的CRT,可以解决此问题。因为cryptlib.lib使用CRT版本的调试。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.