【问题标题】:Mismatch Detected for 'RuntimeLibrary'检测到“RuntimeLibrary”不匹配
【发布时间】:2013-01-20 19:31:21
【问题描述】:

我在 C:\cryptopp 中下载并提取了 Crypto++。我使用 Visual Studio Express 2012 构建了里面的所有项目(按照自述文件中的说明),一切都构建成功。然后我在其他文件夹中创建了一个测试项目,并添加了 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++,应该是最新版本。

【问题讨论】:

标签: c++ hash compilation sha256 crypto++


【解决方案1】:

(这已经在 cmets 中得到了回答,但由于它缺少实际的答案,所以我正在写这个。)

这个问题出现在新版本的 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. Linker Tools Warning LNK4098 在 MSDN 上
  2. /MD, /ML, /MT, /LD (Use Run-Time Library) 在 MSDN 上
  3. Build errors with VC11 Beta - mixing MTd libs with MDd exes fail to link 在 Bugzilla@Mozilla 上

更新:(这是对一个评论的回应,该评论询问为什么必须如此小心。)

如果我们链接在一起的两段代码本身链接并使用标准库,那么标准库对它们来说必须是相同的,除非非常注意如何我们的两个代码片段交互并传递数据。一般来说,我会说,对于几乎所有情况,只需使用完全相同版本的标准库运行时(关于调试/发布、线程,显然是 Visual C++ 的版本,以及迭代器调试等)

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

例如,上面两段代码分别称为AB。 A 针对标准库的一个版本编译,而 B 针对另一个版本。在 A 看来,标准函数返回给它的一些随机对象(例如内存块或迭代器或 FILE 对象或其他)具有特定的大小和布局(请记住,结构布局是在编译时确定和固定的在 C/C++ 中。)出于多种原因,B 对相同对象的大小/布局的想法是不同的(这可能是因为额外的调试信息、数据结构随时间的自然演变等)

现在,如果 A 调用标准库并取回一个对象,然后将该对象传递给 B,并且 B 以任何方式接触该对象,则 B 很可能会弄乱该对象(例如,写入错误的字段,或者过去,等等)

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

当使用 DLL(动态运行时库)而不是 libs(静态运行时库)时,这一切在某些方面变得更加奇怪。

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

我所描述的显然是混合库版本时等待你的实际混乱的淡化和简化版本。我希望它能让您了解为什么不应该这样做!

【讨论】:

  • 我有点困惑。 OP 的 errorLNK2038。由于并非所有库都发生这种情况,我怀疑 Crypto++ 使用了一些 CRT 设置,导致无法混合 CRT 风格 - 通常这只是一个警告 (LNK4098),如果你知道,可能是安全的你做什么(不推荐,但可能有限制,见例如stackoverflow.com/a/19944935/948581)。不过,我不知道为什么 Crypto++ 会受到这种影响。
  • @Tibo:这些不是 DLL 的导入库;我相信 Crypto++ 实际上是与这里的程序静态链接的。这意味着在一个模块中与另一个模块链接的标准库中的任何不匹配(可能)都违反了“一个定义规则”。哪个不好。这曾经不是错误,因为链接器甚至无法检测到这一点(函数/类型名称相同,但它们的主体和定义显着不同),直到 VC10 链接器/图书馆员开始“标记”模块它产生了有关构建配置的额外信息...
  • @Tibo: ...(接上一条评论)例如,查看 OP 报告的第一个错误块。在那里,“RuntimeLibrary”是 Crypto++ 库和 OP 程序的目标文件上的标签,其中一个的值为“MDd_DynamicDebug”,而“ MTd_StaticDebug" 为另一个。这样,尝试将两个目标文件链接在一起的链接器可以检测和报告全新的错误类别,因为生成这些目标文件的链接器使用任何相关信息标记它们,特别是任何可能违反 ODR 的设置。
  • 虽然我非常同意你的观点,但这里仍有一个谜团。至于 OP 的问题,我猜他正在包含 Crypto++ 中的“dll.h”,然后尝试链接静态库而不是 DLL 的导入库。但是我在一台计算机上看到了完全相同的错误,而不是在另一台计算机上(VS2013 Ultimate sp4 -> 错误,VS2013 community sp5 -> ok)...
  • @yzt 我想出了一个解决方案。 Windows 没有使用 /ZW 开关,而是提供了一种通过 COM 使用名为 WRL 的包装器来使用 WinRT API 的方法。只是不使用 /ZW 使编码变得不那么困难,因为它隐藏了 COM 实现细节,但可以在不使用 /ZW 的情况下使用 WinRT。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

    转换可能不成功。唯一成功的是 VCUpgrade 的运行。实际的转换本身失败了,但在您遇到所看到的错误之前您不知道。有关一些详细信息,请参阅 Crypto++ wiki 上的 Visual Studio


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

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


    vs2010.zipvs2010-dynamic.zipvs2005-dynamic.zip 是从 latest GitHub sources 构建的。在撰写本文时(2016 年 6 月 1 日),这实际上是 Crypto++ 5.6.4 之前的版本。如果您使用低级别 Crypto++ 的 ZIP 文件,例如 5.6.2 或 5.6.3,那么您会遇到一些小问题。

    我知道有两个小问题。首先是bench.cpp to 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.hcpu.hcpu.cpp。 “微妙之处”是你不会意识到你正在学习一个表现不佳的课程。

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

    【讨论】:

    • 我按照 cryptopp wiki 中的说明下载了 vs2010-dynamic.zip 并将其内容粘贴到 cryptopp563 代码中。构建并丢失了一些源文件。没问题,wiki 说 zip 用于 github 上的最新项目,只需删除所有丢失的文件。已删除。现在项目只是没有构建:4 个链接错误,一个示例:错误 LNK2001:未解析的外部符号“void __cdecl OutputResultOperations(char const *,char const *,bool,unsigned long,double)”(?OutputResultOperations@@YAXPBD0_NKN@ Z)
    • 原来项目中缺少一个 bench.cpp。但即使在那之后它也没有编译,直到我将这个修复应用到 f​​iptest.cpp github.com/weidai11/cryptopp/pull/151/files?diff=split 我希望他们能在这个中做出一些排序,比如将项目 zip 文件添加到 git 或其他东西中。是的,我忘了说我的编译器是 VS2015 更新 2。最重要的是,按照我写的提示进行操作。
    • @Yaniv - 对于第一条评论,您有什么建议可以让其他用户不会遇到问题?对于第二条评论,我们计划在对补丁进行全面测试后采用该补丁。在此期间我们有什么可以做的吗? (我在此答案中添加了其他信息,但我想确保用户没有问题)。
    • 首先,非常感谢您这样做。 Crypto++ 真的很震撼。关于构建问题,尽量保持 windows sln 和项目文件与项目中的最新文件兼容,当然,由于这些变化,这些 windows 构建应该以某种方式链接到代码库,甚至可能在源代码树上。如果太多了,至少要确保 Visual Studio 构建环境的 zip 文件与当前稳定的官方版本兼容。
    • 关于 fiptest.cpp 的补丁 - VS2015 似乎有些不同,所以我想任何希望使用 VS2015 的人都需要应用这个补丁。这只是#ifdef 块中的另一种情况,它似乎为 VS2015 定义了正确的调试回调,而且手动修补真的很容易。
    【解决方案4】:

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

    【讨论】:

      猜你喜欢
      • 2016-12-30
      • 2023-01-30
      • 2014-12-06
      • 2019-04-17
      • 2015-05-07
      • 2021-01-29
      • 1970-01-01
      • 2020-12-13
      • 2012-10-29
      相关资源
      最近更新 更多