CRT 库类型

2024-03-03

我试图更好地掌握 Visual Studio 2013 中的 CRT 库选项(C++ -> 代码生成 -> 运行时库)以及如何知道选择哪个选项(以及何时更改默认值)。

From MSDN http://support.microsoft.com/en-us/kb/140584:

可重用库及其所有用户应使用相同的 CRT 库类型,因此应使用相同的编译器开关。

因此,我的理解是,如果您要链接第三方库,则应该使用与构建该库相同的 CRT 版本。构建库的人应该指定构建中使用的 CRT 选项。

有没有办法仅通过查看 .lib 文件来确定使用的是哪个 CRT 版本?

更重要的是,如果您不链接任何第三方库,您将如何决定使用哪个选项?您什么时候会考虑更改默认值?


简短回答:

所以,我的理解是,如果您与第三方链接 库,您应该使用用于构建的相同 CRT 版本 图书馆。构建库的人应该指定什么 CRT 选项 在构建中使用了。

这是最不容易出错的选项。可以混合运行时,但如果这样做,您可能会遇到意想不到的错误。

有没有一种方法可以通过查看来确定使用的是哪个 CRT 版本 在 .lib 文件中?

我不知道.lib其本身,但如果第三方代码有 DLL 或 EXE,您可以使用 Windows 查看它依赖于哪个 CRT DLL依赖步行者 http://www.dependencywalker.com/ tool.

如果它是静态库,并且您的代码的 CRT 选择不匹配,则您在构建时会看到警告。

更重要的是,如果您 没有与任何第三方库链接?你什么时候会考虑 更改默认值?

对于最简单的部署,静态链接是最好的;您可以单独发送可执行文件,它就会运行。对于具有多个 EXE 和 DLL 的大型项目,如果静态链接,代码大小将会更大。如果同一进程中有多个模块(EXE 加上 1 个或多个您自己的 DLL),最好共享相同的 CRT 代码。

更多细节(基于我之前写的博客文章):


库变体

您可以根据 C/C++ 运行时库的四种变体构建代码:

  • 多线程调试DLL
  • 多线程DLL
  • 多线程调试
  • 多线程

您可以通过右键单击 Visual Studio 中的项目并选择“属性”,然后单击代码生成下的选项C/C++在弹出的对话框中,然后转到运行时库财产。

请记住,此设置是针对每个配置的,因为您需要选择一个Debug运行时库Debug配置,以及Release运行时库Release配置。

有什么不同?

The DLL运行时库选项意味着您可以动态链接到 C/C++ 运行时,并且为了让您的程序运行,DLL需要在你的程序可以找到它的地方(稍后会详细介绍)。

未提及 DLL 的选项(多线程调试 and 多线程发布)使您的程序与运行时静态链接。这意味着您不需要外部 DLL 来运行程序,但是您的程序会因为额外的代码而变得更大,并且还有其他原因您可能不想选择它。

默认情况下,当您在 Visual Studio 中创建新项目时,它将使用DLL运行。

运行时名称中的多线程是过去同时存在非线程安全和多线程 C/C++ 运行时的遗留问题。你将永远使用多线程即使您自己的应用程序是单线程的,也可以使用现代 Visual Studio 运行时。

部署 DLL 运行时

如果您要链接 DLL 运行时,那么您必须考虑在发布程序(测试和客户)时如何部署它们。

如果你送货Debug为您的测试团队构建,请确保您也提供 DLL 运行时的调试变体。

另外,不要忘记获得正确的架构(例如x86 vs x64).

可再发行安装程序

Microsoft 提供了可再发行的软件包来安装Release(但不是Debug) DLL。通过搜索类似的内容可以很容易地找到这些Visual C++ 可再发行版 2013(将 Visual Studio 版本替换为您需要的版本)。您也可以直接前往最新支持的 Visual C++ 下载 http://support.microsoft.com/kb/2019667在微软的网站上。

这些可再发行包是可执行文件,您可以从程序的安装程序中调用它们(或者您可以手动运行它们以设置测试环境)。请注意,x86 和 x64 有单独的可再发行版本。

合并模块

如果您正在构建 MSI 安装程序,您可以合并合并模块 https://msdn.microsoft.com/en-us/library/aa369820%28v=vs.85%29.aspx对于您在安装程序包中使用的 C/C++ 运行时。这些合并模块通常位于C:\Program Files (x86)\Common Files\Merge Modules。例如,Visual Studio 2013 的 x86 C/C++ 运行时合并模块称为Microsoft_VC120_CRT_x86.msm.

请注意,这些合并模块名称中的版本号不是基于年份的产品版本,而是内部版本号。维基百科上的这个表 http://en.wikipedia.org/wiki/Microsoft_Visual_Studio#History显示版本号之间的映射以避免混淆。

与上面的独立可执行可再发行安装程序不同,合并模块也有调试变体。

某些版本的 Visual Studio 支持视觉工作室安装程序项目类型(下设置和部署类别在其他项目类型),如果您将程序项目的输出包含在这些安装程序之一中,则运行时的合并模块将自动包含在内。您还可以使用此技巧来获取将安装Debug用于内部测试目的的运行时(任何虚拟 C/C++ 项目都可以,它不必实际安装您的程序)。

从 Redist 文件夹复制

您还可以将 DLL 从 Visual C++ 安装中的 redist 文件夹复制到程序安装位置。例如,对于 Visual Studio 2013,您将在类似位置找到 x64 C/C++ 运行时库C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\redist\x64\Microsoft.VC120.CRT\.

调试变体可以在类似的地方找到C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\redist\Debug_NonRedist.

(根据您的 Visual Studio 版本和安装位置调整路径)。

混合 C/C++ 运行时

在理想情况下,您将使用相同的 C/C++ 运行时库变体(Debug vs Release, DLL vs 静态链接),并且全部来自同一版本的 Visual Studio,对于链接到程序中的所有库。

如果您混合运行时,您可能会遇到链接器错误,您的程序可能根本无法运行,或者更糟糕的是,它可能看起来可以工作,但仅在某些情况下崩溃或给出错误的结果。

忽略默认库

一个常见的情况是您只有Release某些第三方库的版本,但您仍然希望能够构建Debug使用此库的您自己的代码的变体。另一种情况是,您有一个使用静态 C/C++ 运行时的库,并且您想要DLL程序中的版本,或者相反。

如果第三方库是 C 代码,那么您可能能够摆脱这一点并让它实际工作,使用/NODEFAULTLIB链接器选项 https://msdn.microsoft.com/en-us/library/3tz4da4a.aspx.

如果库是 C++ 代码,您可能会运气不好,因为生成的代码中有太多与特定运行时中的符号相关联。

这些是不同的库名称:

  • LIBCMT库:静态链接的发布运行时(也称为多线程)
  • LIBCMTD库:静态链接的调试运行时(也称为多线程调试)
  • MSVCRT库:动态链接的发布运行时(也称为多线程深度学习L)
  • MSVCRTD库:动态链接的调试运行时(也称为多线程调试DLL)

请记住,您想要忽略的运行时库是第三者代码正在使用,即它将与您自己的程序正在使用的库不同。如果您查看构建输出,系统将提示您选择正确的输出,例如:

LINK : warning LNK4098: defaultlib 'LIBCMTD' conflicts with use of other libs; use /NODEFAULTLIB:library

您可以通过右键单击项目并选择来指定要忽略的库特性,单击Input条目下Linker并将运行时库名称添加到条目中。

跨越模块边界

您还可能以更微妙的方式跨模块边界(例如在 EXE 和它加载的 DLL 之间)遇到 C/C++ 运行时不匹配问题。

例如,C 库中的数据结构可能由不同的运行时定义不同。我见过这会导致使用 DLL 的程序崩溃,而该 DLL 使用了FILE*在它的 API 中。文件是使用一个 C 运行时在一个模块中打开的,并由具有不同、不兼容实现的另一个模块进行交互。更安全的选择包括传递 Windows APIHANDLE诸如此类的对象,或者以与运行时无关的方式包装文件交互。

不同的运行时还使用自己的内存堆进行分配。如果一个对象在一个堆上的一个模块中分配,但在另一个模块中释放,则如果 C/C++ 运行时不匹配,则可能会发生崩溃。当然,这仅适用于使用 C 或 C++ 运行时的分配,例如malloc or new。例如,如果到处都使用默认的 Windows 进程堆,则一切都很好。

请注意,如果模块静态链接到 C/C++ 运行时,即使它们链接的运行时是相同的变体,它们也会遇到此问题,因为仍然存在两个不同的运行时,它们拥有自己的内存堆。因此,在这种情况下您将需要使用 DLL C/C++ 运行时。

如果运行时实现的功能(例如异常或带有 vtable 的类)跨越模块边界,那么在每个模块中使用(相同版本的)DLL 运行时也是明智的,尽管某些不匹配的组合在实践中可能会起作用。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CRT 库类型 的相关文章

  • 尚未注册类型“IServiceProviderFactory[Autofac.ContainerBuilder]”的服务

    当运行以下命令添加数据库迁移脚本时 出现以下错误 dotnet ef migrations add InitialCreate v o Migrations context MyContext 访问 Microsoft Extensions
  • 通过 SocketCAN 进行 boost::asio

    我正在考虑利用升压阿西奥 http www boost org doc libs 1 49 0 doc html boost asio html从a读取数据套接字CAN http en wikipedia org wiki SocketCA
  • 使用 mono/nunit-console/4 在 Mac OS X 控制台上运行测试

    我安装了 Max OS X 10 11 1 上面装有 Xamarin 我编写了简单的测试类 只是为了测试在 Mac OS X 和 Ubuntu 上运行 Nunit 测试 该类实际上有一个返回字符串的方法 using System names
  • 如何在 DataColumn.Expression 中使用 IF/ELSE 或 CASE?

    我有一个包含 1 列的表 状态 我想添加另一列名为 Action 的列 其值如下 如果 Status Yes 则 Action Go 否则 Action Stop 我使用以下代码添加到 操作 列中 但它不起作用 myDataTable Co
  • 更改 Qt OpenGL 窗口示例以使用 OpenGL 3.3

    我正在尝试更改 Qt OpenGL 示例以使用更现代的 opengl 版本 330 似乎合适 所以我做了 在 main cpp 上设置版本和配置文件 设置着色器版本 更改着色器以使用统一 它现在构建没有任何错误 但我只看到一个空白窗口 我错
  • 我如何在 C# .NET(win7 手机)中使用“DataContractJsonSerializer”读入“嵌套”Json 文件?

    我有一个问题 如果我的 json 文件看起来像这样 Numbers 45387 Words 空间桶 我可以很好地阅读它 但是如果它看起来像这样 Main Numbers 45387 Words 空间桶 某事 数字 12345 单词 克兰斯基
  • 信号处理程序有单独的堆栈吗?

    信号处理程序是否有单独的堆栈 就像每个线程都有单独的堆栈一样 这是在 Linux C 环境中 来自 Linux 手册页signal 7 http kernel org doc man pages online pages man7 sign
  • fprintf() 线程安全吗?

    我正在为野人就餐问题的某些变量编写一个 C 解决方案 现在 我创建线程 每个线程都将 FILE 获取到同一个调试文件 在线程内我正在使用 fprintf 进行一些打印 打印的语句不受任何类型的互斥锁等保护 我没有在调试文件中观察到任何交错行
  • 单例模式和 std::unique_ptr

    std unique ptr唯一地控制它指向的对象 因此不使用引用计数 单例确保利用引用计数只能创建一个对象 那么会std unique ptr与单例执行相同 单例确保只有一个实例属于一种类型 A unique ptr确保只有一个智能指针到
  • 如何从文本文件读取整数到数组

    这就是我想做的 我对此有些不满 但我希望你能容忍我 这对我来说是一个非常新的概念 1 在我的程序中 我希望创建一个包含 50 个整数的数组来保存来自文件的数据 我的程序必须获取用户的文档文件夹的路径 2 文件的名称为 grades txt
  • 如何在服务器端按钮点击时关闭当前标签页?

    我尝试在确认后关闭当前选项卡 因此我将以下代码放在确认按钮的末尾 但选项卡没有关闭 string jScript ClientScript RegisterClientScriptBlock this GetType keyClientBl
  • C++ php 和静态库

    我创建了一个library a 其中包含 cpp 和 h 文件 其中包含很多类 嵌套类和方法 我想在 php 示例中包含这个静态库并尝试使用它 我想提一下 我是 php 新手 我已经在 test cpp 文件中测试了我的 libray a
  • 检查 RoutedEvent 是否有任何处理程序

    我有一个自定义 Button 类 当单击它时 打开特定窗口 它总是执行相同的操作 我添加了一个可以在按钮的 XAML 中分配的 Click 事件 就像常规按钮一样 当它被单击时 我想执行 Click 事件处理程序 如果已分配 否则我想执行默
  • 将二进制数据从 C# 上传到 PHP

    我想将文件从 Windows C 应用程序上传到运行 PHP 的 Web 服务器 我知道 WebClient UploadFile 方法 但我希望能够分块上传文件 以便我可以监控进度并能够暂停 恢复 因此 我正在读取文件的一部分并使用 We
  • 无法在内存位置找到异常源:cudaError_enum

    我正在尝试确定 Microsoft C 异常的来源 test fft exe 中 0x770ab9bc 处的第一次机会异常 Microsoft C 异常 内存位置 0x016cf234 处的 cudaError enum 我的构建环境是 I
  • 将标量添加到特征矩阵(向量)

    我刚刚开始使用 Eigen 库 无法理解如何向所有矩阵成员添加标量值 假设我有一个矩阵 Eigen Matrix3Xf mtx Eigen Matrix3Xf Ones 3 4 mtx mtx 1 main cxx 104 13 error
  • C# 中的 strstr() 等效项

    我有两个byte 我想找到第二个的第一次出现byte 在第一个byte 或其中的一个范围 我不想使用字符串来提高效率 翻译第一个byte to a string会效率低下 基本上我相信就是这样strstr 在 C 中做 最好的方法是什么 这
  • cout 和字符串连接

    我刚刚复习了我的 C 我尝试这样做 include
  • 如何在 DropDownList 中保留空格 - ASP.net MVC Razor 视图

    我在视图中通过以下方式绑定我的模型 问题是我的项目文本是格式化文本 单词之间有空格 如下所示 123 First 234 00 123 AnotherItem 234 00 123 Second 234 00 我想保留此项目文本中的空格 即
  • 矩阵到数组 C#

    这将是转换方阵的最有效方法 例如 1 2 3 4 5 6 7 8 9 into 1 2 3 4 5 6 7 8 9 in c 我在做 int array2D new int 1 2 3 4 5 6 7 8 9 int array1D new

随机推荐

  • 从 JPQL 查询返回 JPA 实体的子集作为映射数组?

    在 JPQL 中 可以使用构造函数表达式来请求实体的子集 例如 SELECT NEW example EmployeeDetails e name e salary e department name FROM Employee e 它返回
  • GetTickCount() 实际测量什么?

    我想知道 Windows API 是做什么的GetTickCount http msdn microsoft com en us library windows desktop ms724408 28v vs 85 29 aspx实际测量
  • 嵌套多线程操作跟踪

    我有一个类似的代码 void ExecuteTraced Action a string message TraceOpStart message a TraceOpEnd message 回调 a 可以再次调用 ExecuteTraced
  • Google Sceneform – 它已被弃用吗?有替代品吗? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我在我的 ARCore 项目 Sceneform 中使用 看来这个项目现在被称为Archived htt
  • 洗牌向量 - 样本()的所有可能结果?

    我有一个包含五个项目的向量 my vec lt c a b a c d 如果我想将这些值重新排列到一个新的向量中 随机播放 我可以使用sample shuffled vec lt sample my vec 简单 但sample 函数只给我
  • Haskell 中的验证

    我有一些需要验证的嵌套记录 我想知道惯用的 Haskell 方法是什么 简化一下 data Record Record recordItemsA ItemA recordItemB ItemB deriving Show data Item
  • 打开 JSX 文件时如何使 VS Code 将语言更改为 JavaScript React

    目前 当我打开一个 jsx文件的默认语言是纯 JavaScript 有没有办法设置编辑器根据文件扩展名更改语言 理想情况下 我可以将此设置放入本地设置配置文件或工作区特定配置文件中 我使用的版本是Version 1 15 0 insider
  • 更改 API 级别 Android Studio

    我想将 Android Studio 中的最低 SDK 版本从 API 12 更改为 API 14 我尝试在清单文件中更改它 即
  • Eclipse 中的“Android Private Libraries”文件夹是什么?

    我最初以为它是专门用于像支持库这样的官方库的 然而 每当我使用 添加到构建路径 菜单项添加自定义 JAR 时 它都会自动显示在 引用库 和 Android 私有库 中 其中之一是多余的 因为在构建时导出两者是没有意义的 此外 Android
  • 命令不同步,您现在无法运行此命令

    我正在尝试使用 mysqldb 创建一些表 问题是当执行python脚本时db pymysql 抛出错误 mysql exceptions ProgrammingError 2014 命令不同步 您现在无法运行此命令 db py impor
  • 如何使用 Dagger2 将 Activity 范围内的依赖项替换为模拟

    我的 Activity 中有范围依赖项 我想用一些模拟来测试该 Activity 我读过有关建议在测试期间用测试组件替换应用程序组件的不同方法 但我想要的是替换活动组件 例如 我想在 MVP 设置中针对模拟演示者测试活动 我相信通过在 Ac
  • PHP:如何将无穷大或 NaN 数字编码为 JSON?

    显然 无穷大和 NaN 不是 JSON 规范的一部分 因此这个 PHP 代码 numbers array numbers positive infinity INF numbers negative infinity INF numbers
  • 大数组上的分段错误

    以下代码在 2GB 机器上运行时出现分段错误 但在 4GB 机器上运行 int main int c 1000000 cout lt lt done n return 0 数组的大小仅为 4Mb C 中可以使用的数组的大小是否有限制 您可能
  • Ehcache - 找不到生成器的缓存名称

    我已经浏览了这里提出的很多类似问题 但我仍然无法找到解决方案 所以这是我的问题 我正在尝试在 Spring Boot 中设置 Ehcache Spring 2 2 6 RELEASE Ehcache 3 8 1 缓存服务 I ve got
  • data-* 属性可以包含 HTML 标签吗?

    I E img src world jpg 据我了解 它基本上是有效的 但最好使用 HTML 实体 来自HTML 4 参考 http www w3 org TR WD html40 970708 charset html 您还应该在属性值中
  • 如何显示外部 PostgreSQL 连接的 WORK_MEM?

    我知道我可以使用SHOW WORK MEM 在psql中查看当前使用的连接的值 但其他连接呢 我有一个应用程序可以打开许多连接并动态更改WORK MEM基于上下文 我想监控这些WORK MEM进行更改以确保它们得到应用 换句话说 我想 调整
  • 有效的 MFC ID 范围

    这让我很困惑 我正在读这个技术说明 https learn microsoft com en gb cpp mfc tn020 id naming and numbering conventions它指出 Prefix Resource t
  • 如何在 .xib 文件上创建的 UIViewController 中设置 UITableView

    我有一堂这样的课 interface ExerciseLogDetails UIViewController
  • AVURLAsset获取视频大小

    这真是令人沮丧 我正在尝试获取 AVURLasset 的大小 但尽量避免naturalSize因为 Xcode 告诉我 这在 iOS5 中已被弃用 但是 替代品是什么 我找不到任何关于如何在不使用 naturalsize 的情况下获取视频尺
  • CRT 库类型

    我试图更好地掌握 Visual Studio 2013 中的 CRT 库选项 C gt 代码生成 gt 运行时库 以及如何知道选择哪个选项 以及何时更改默认值 From MSDN http support microsoft com en