vs的运行库 MT MTd MD MDd区别

2023-11-13

MT: mutithread  Static,多线程库,编译器会从运行时库里面选择多线程静态连接库来解释程序中的代码,即连接LIBCMT.lib库

MTd:mutithread debug Static ,多线程调试版,连接LIBMITD.lib库

MD:mutithread  +Dynamic,多线程动态库,连接MSVCRT.lib库,这是个导入库,对应动态库为MSVCRT.dll

MDd: mutithread +Dynamic+debug,多线程动态调试库,连接MSVCRTD.lib库,对应动态库为MSVCRTD.dll

具体见:

选项         

说明

/MD

使应用程序使用运行库的多线程并特定于 DLL 的版本。 定义 _MT 和 _DLL,并使编译器将库名 MSVCRT.lib 放入 .obj 文件中。

用此选项编译的应用程序静态链接到 MSVCRT.lib。 此库提供允许链接器解析外部引用的代码的层。 实际工作代码包含在 MSVCR100.DLL, 中,该库必须在运行时对于与 MSVCRT.lib 链接的应用程序可用。

/MDd

定义 _DEBUG_MT 和 _DLL,并使应用程序使用运行库的调试多线程并特定于 DLL 的版本。 它还使编译器将库名 MSVCRTD.lib 放入 .obj 文件中。

/MT

使应用程序使用运行库的多线程静态版本。 定义 _MT 并使编译器将库名 LIBCMT.lib 放入 .obj 文件中,以便链接器使用 LIBCMT.lib 解析外部符号。

/MTd

定义 _DEBUG 和 _MT。 此选项还使编译器将库名 LIBCMTD.lib 放入 .obj 文件中,以便链接器使用 LIBCMTD.lib 解析外部符号。

/LD

创建 DLL。

将 /DLL 选项传递到链接器。 链接器查找 DllMain 函数,但并不需要该函数。 如果没有编写 DllMain 函数,链接器将插入返回 TRUE 的 DllMain 函数。

链接 DLL 启动代码。

如果命令行上未指定导出 (.exp) 文件,则创建导入库 (.lib);将导入库链接到调用您的 DLL 的应用程序。

将 /Fe(命名 EXE 文件) 解释为命名 DLL 而不是 .exe 文件;默认程序名成为基名称.dll 而不是基名称.exe。

除非显式指定 /MD,否则将暗指 /MT

/LDd

创建调试 DLL。 定义 _MT 和 _DEBUG

vs 工具上修改地方是:“项目 -> C/C++ ->代码生成 -> 运行库 

1.以小写“d”结尾的选项表示的DEBUG版本的,没有“d”的为RELEASE版本。大型项目中必须要求所有组件和第三方库的运行时库是统一的,否则将会出现LNK2005井喷。

2.多线程调试和多线程DLL调试的区别是动态链接还是静态链接C运行时库(C runtime Library, CRT)。

如果是动态链接(MD/MDd),你的程序就依赖C运行时的动态链接库(比如VS2010的msvr100.dll),当你的程序在其他没有这个dll的电脑上运行就会出现错误(找不到这个dll)。

如果是静态链接(MT/MTD),C运行库直接链接到你的程序里,你的程序就不依赖C运行时库的dll了。

微软是推荐是用动态链接的,因为这种链接方式可以减少可执行文件的大小、可以减少内存的使用、避免链接问题。

 /MT和/MTd

  /MT和/MTd表示采用多线程CRT库的静态lib版本。该选项会在编译时将运行时库以静态lib的形式完全嵌入。该选项生成的可执行文件运行时不需要运行时库dll的参加,会获得轻微的性能提升,但最终生成的二进制代码因链入庞大的运行时库实现而变得非常臃肿。当某项目以静态链接库的形式嵌入到多个项目,则可能造成运行时库的内存管理有多份。(即会有多个堆,容易使释放内存出现问题)。

容易出现关于__acrt_first_block == header异常,根本的原因是对象在析构时不正确的释放内存导致的。见:c++:动态库接口函数返回stl对象的设计原则塈‘__acrt_first_block == header’异常原因分析_10km的专栏-CSDN博客

  /MD和/MDd

  /MD和/MDd表示采用多线程CRT库的动态dll版本,会使应用程序使用运行时库特定版本的多线程DLL。链接时将按照传统VC链接dll的方式将运行时库MSVCRxx.DLL的导入库MSVCRT.lib链接。当多项目以MD方式运作时,其内部会采用同一个堆

 结论:/MD和/MDd将是潮流所趋,/ML和/MLd方式请及时放弃,/MT和/MTd在非必要时最好也不要采用了

这是个很典型的问题,在MSDN上也有描述。问题是这样的:

在一个DLL里面分配内存,然后在DLL的调用者EXE那里释放内存。

当DLL和EXE里面有一个是使用MT连接CRT的时候就有问题。如果DLL和EXE都使用MD,那么就没有问题。

解决办法:

1.exe和dll 都使用MDd运行库。

2.在dll中封装一个模板类,使模板类实现。

3.在dll中使用虚函数,目的就是是创建和删除都是使用同一个crt. 如果我们创建2个虚函数,一个用来分配内存,一个用来释放内存。在对象构造的时候,这个对象的虚表里面就已经指向了创建这个对象的模块里面的CRT的new和delete,那么当我们在DLL里面调用虚函数来释放的时候,系统会为我们找到构造对象时候的释放函数。这样就没有问题了。

见代码

class MyWrapperEx
{
public:
    explicit MyWrapperEx(int* p) : m_p(p)
    {}

    virtual ~MyWrapperEx()
    {
        if (m_p)
        {
            delete m_p;
            m_p = nullptr;
        }
    }
    virtual void ChangeValue(int isize)
    {
        int* p = new int[isize];
        if (m_p)
        {
            delete m_p;
            m_p = p;
        }
    }
private:
    int* m_p;
};

void funcWrapperdll(MyWrapperEx& p)
{
    p.ChangeValue(2);
}

class MyWrapperEx;
int main()
{
    MyWrapperEx w2(new int);
    funcWrapperdll(w2);

}

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

vs的运行库 MT MTd MD MDd区别 的相关文章

  • 添加 Nullable int 时保持 null?

    我想添加可为空的int 并保留null当所有值都是null 我想要这个结果 1 2 3 1 null 1 null null null O null 0 问题是 如果我将一个值与 null 相加 结果为 null int i1 1 int
  • 在路由mvc 4中添加公司名称

    我一直在尝试为 Facebook 等用户提供在 URL 中添加公司名称的选项 http localhost 50753 MyCompany Login 我尝试过不同的网址 但没有成功 routes MapRoute name Default
  • 删除是如何工作的? [复制]

    这个问题在这里已经有答案了 可能的重复 C 编程 free 如何知道要释放多少 https stackoverflow com questions 1518711 c programming how does free know how m
  • 在现代 C++ 中,临时生命周期延长何时有用?

    在 C 中 您可以将函数的返回值 返回值 而不是引用 绑定到 const 引用 并且代码仍然有效 因为该临时对象的生命周期将延长到作用域末尾 例如 std string get string return abc void f const
  • 将表(行)与 OpenXML SDK 2.5 保持在一起

    我想在 Word 文档中生成多个表 每行 2 行 但我想将这两行保留在一起 如果可能的话 new KeepNext 第一行不起作用 new KeepNext 第一行的最后一段不起作用 new CantSplit 放在桌子上不起作用 在所有情
  • 获取 boost Spirit 语法中的当前行

    我正在尝试使用 boostspirit 获取正在解析的文件的当前行 我创建了一个语法类和结构来解析我的命令 我还想跟踪在哪一行找到命令并将其解析到我的结构中 我将 istream 文件迭代器包装在 multi pass 迭代器中 然后将其包
  • 使用查询表达式对 List 进行排序

    我在使用 Linq 订购这样的结构时遇到问题 public class Person public int ID get set public List
  • UI 函数在快速事件完成之前触发

    我有一个停靠在 Silverlight 应用程序中的 Web 浏览器框架 有时会在其上弹出全窗口 XAML Silverlight UI 元素 我已经或多或少修复了一个老问题 即 Web 框架的内容似乎与 Silverlight 内容不能很
  • 如何在三个 IEnumerable 上使用 Zip [重复]

    这个问题在这里已经有答案了 可能的重复 使用 Linq 从 3 个集合创建项目 https stackoverflow com questions 5284315 create items from 3 collections using
  • 在 asp.net MVC 中使用活动目录进行身份验证

    我想使用活动目录对我的 asp net mvc 项目中的用户进行身份验证 在网上冲浪了几个小时后 我没有找到任何对我有用的东西 我已经看到了所有结果 但什么也没有 我尝试按照许多帖子的建议编辑我的 web config 如果有人可以帮助我提
  • 使用具有抗锯齿功能的 C# 更改抗锯齿图像的背景颜色

    我有一个图像需要更改背景颜色 例如 将下面示例图像的背景更改为蓝色 然而 图像是抗锯齿的 所以我不能简单地用不同的颜色替换背景颜色 我尝试过的一种方法是创建第二个图像 仅作为背景 并更改其颜色并将两个图像合并为一个图像 但是这不起作用 因为
  • 使用 GCC 生成可读的程序集?

    我想知道如何使用GCC http en wikipedia org wiki GNU Compiler Collection在我的 C 源文件中转储机器代码的助记符版本 这样我就可以看到我的代码被编译成什么 你可以使用 Java 来做到这一
  • 在 OpenGL 中渲染纹理 1 到 1

    所以我想做的是使用 OpenGL 和 C 将纹理渲染到平面上 作为显示图像的一种方式 但是我需要确保在渲染纹理时没有对纹理进行任何处理 抗锯齿 插值 平滑 模糊等 这是 OpenGL 处理渲染纹理的默认方式吗 或者是否需要设置一些标志才能禁
  • WIX 工具集 - 自定义操作命令无法正确检测 Windows 10 版本

    我有一个安装程序 可以部署并运行单独的 exe文件以将驱动程序部署到系统 不幸的是 微软似乎已经放弃了对VersionNTWindows 10 及更高版本中的宏 所以我实施了另一篇文章中建议的方法 https stackoverflow c
  • ASP.NET MVC 路由:如何从 URL 中省略“索引”

    我有一个名为 StuffController 的控制器 具有无参数索引操作 我希望从表单中的 URL 调用此操作mysite com stuff 我的控制器定义为 public class StuffController BaseContr
  • .NET 4 的条件编译[重复]

    这个问题在这里已经有答案了 可能的重复 条件编译和框架目标 https stackoverflow com questions 2923210 c sharp conditional compilation and framework ta
  • CUDA 8 编译错误 -std=gnu++11

    我正在尝试转换一些代码以使用 CUDA 并且我认为我遇到了兼容性问题 我们使用CMake 这些是我使用的 gcc 和 CUDA 版本 gcc version gcc Ubuntu 5 4 0 6ubuntu1 16 04 5 5 4 0 2
  • 在 C#.NET 中安全删除文件

    在我正在做的一个项目中 我想为用户提供 安全 删除文件的选项 例如 用随机位或 0 覆盖它 在 C NET 中是否有一种简单的方法可以做到这一点 效果如何 你可以调用系统内部删除 http technet microsoft com en
  • 如何得知客户端从服务器的下载速度?

    根据客户的下载速度 我想以低质量或高质量显示视频 任何 Javascript 或 C 解决方案都是可以接受的 Thanks 没有任何办法可以确定 您只能测量向客户端发送数据的速度 如果没有来自客户端的任何类型的输入来表明其获取信息的速度 您
  • 为什么匹配模板类上的部分类模板特化与没有模板匹配的另一个部分特化不明确?

    这个问题可能很难用标题中的句子来描述 但这里有一个最小的例子 include

随机推荐

  • 初等变换法求解线性方程组

    初等变换 通过初等行 列同理 变换把增广矩阵变为简化阶梯型矩阵的线性方程组求解算法 具体步骤 枚举每一列 找到枚举的当前列绝对值最大数的所在行 将该行换到最上面一行 第r行 将该行第一个数 该行第c列元素 消成1 将该行第一个元素 该行第c
  • PCB中如何区分电源线和信号线

    在电路设计中 我们需要区分电源线和信号线 电源线主要负责传输电能和提供稳定的电压给整个电路系统 而信号线则传输各种数据 信息和控制电路 当我们开始画 PCBA 时 通常会采用颜色编码来区分电源线和信号线 以下是一些常见的方法 电源线通常使用
  • 常用邮件客户端软件设置

    文章来源 http service mail qq com cgi bin help subtype 1 id 28 no 371 2 您可以使用支持POP3的客户端软件 例如Foxmail或Outlook 收发您的邮件 请配置您的电子邮件
  • CentOS7搭建httpd服务

    文章目录 httpd 1 httpd安装 使用yum安装 httpd命令 curl命令 编译安装httpd 2 4 2 httpd常用配置 访问控制法则 3 虚拟主机 相同ip不同端口的配置 不同IP相同端口配置 相同IP相同端口不同域名配
  • QT Creator工具介绍及使用

    一 QT的基本概念 QT主要用于图形化界面的开发 QT是基于C 编写的一套界面相关的类库 如进程线程库 网络编程的库 数据库操作的库 文件操作的库等 如何使用这个类库 类库实例化对象 构造函数 gt 学习类库中方法 函数 的使用 gt 后台
  • 今天觉得自己太菜了!!!!

    今天觉得自己太菜了 转载于 https www cnblogs com zhangzheny archive 2007 01 24 629460 html
  • 如何检测tensorflow是否使用CPU还是GPU计算

    输入如下命令 python import tensorflow as tf sess tf Session config tf ConfigProto log device placement True 若包含CPU信息 则使用了CPU 若
  • GBDT 学习

    花絮 最近加班疯掉了 比九九六还要多 不行啊 这个便宜一定要从老板身上占回来 另外不知道朋友们是怎么学习一个新算法的 不过我一般是直接百度很多关于这个算法的博客来看 你会发现有些地方可能相互补充 有的地方可能互相矛盾 这种情况可不少见 总之
  • python是一门面向对象的编程语言_python面向对象(面向对象、面向过程、类、参数self)...

    年轻人 你渴望力量吗 你渴望拥有对象吗 让我们面向对象 重建 家园 吧 一 面向对象的简介 众所周知 python是一门面向对象的编程语言 但是 你知道什么是面向对象吗 在说面向对象之前 我们先来说一说什么是对象 之前的博客有简单涉入 一
  • ANT 安装使用及build.xml文档模板

    一 安装 下载地址 http archive apache org dist ant 0 前提 已经正确设定了JAVA HOME的系统变量 1 直接解压 到D apache ant 1 7 2 系统环境变量中设置 path 加上 D apa
  • chatgpt赋能powershell

    最近chatgpt非常火爆 获得超高曝光度的同时 也让大家对ai和ai工具有了新的认识 关于chatgpt 可以参考这篇文章 今天主要推荐一个可以与powershell集成的ai工具 其后端也是openai的服务 可以有效提高工作效率 Po
  • vue3 element plus NavMenu 导航无法选中(同级页面跳转,导航无法高亮)

    需求 导航选中的是公司信息 当跳转到公司信息编辑的时候 上面的导航公司信息还是要选中状态 点击导航 回到信息展示页面 下面是我的路由 在vue2里面 使用element ui 像下面这样做是可以的 动态给el menu item的index
  • 第十一届蓝桥杯大赛软件类省赛第二场 Java 大学 B试题 B: 寻找 2020 解答

    说明 以下介绍三种方法 三者的区别仅在于文件读取方式不同 方法1直接把 txt文件复制粘贴到console控制台上 使用了Scanner类 方法2和方法3都是从电脑文件夹读取文件 但是具体读取细节有些差别 方法2使用了io接口的三个包 Fi
  • Lua 数据类型 —— 表

    一 简介 表永远是匿名的 表本身和保存表的变量之间没有固定关系 对于一个表而言 当程序不再有变量指向他时 垃圾收集器会最终删除这个表并重用其占用的内存 Lua 不会进行隐藏拷贝或创建新表 操作的都是指向表的指针 二 元素 1 键 表的键可以
  • 2.7 深入理解ContentProvider

    第7章 深入理解ContentProvider 7 1 概述 本章重点分析ContentProvider SQLite Cursor query close函数的实现及ContentResolver openAssetFileDescrip
  • 线程安全(上)

    前言 在多线程中 并不是说知道怎么使用就完事了 学习完如何使用多线程之后 我们了解到多线程的并发性和随机调度的特性是我们程序员不容易控制的 所以一旦操作不当就会带来许多安全问题 那我们就开始学习线程安全吧 目录 1 使用多线程带来的风险 硬
  • Rust交叉编译简述 —— Arm

    使用系统 WSL2 Kali Microsoft Store 命令列表 rustup target list 当前官方支持的构建目标架构列表 rustup target add aarch64 unknown linux gnu 添加目标架
  • Tensorflow错误InvalidArgumentError see above for traceback): No OpKernel was registered to support Op

    调用tensorflow gpu运行错误 错误信息如下 2023 06 21 15 36 14 007389 I tensorflow core platform cpu feature guard cc 141 Your CPU supp
  • 十三、java版 SpringCloud分布式微服务云架构之Java Character 类

    Java Character 类 Character 类用于对单个字符进行操作 Character 类在对象中包装一个基本类型 实例 char ch a Unicode 字符表示形式 char uniChar u039A 字符数组 char
  • vs的运行库 MT MTd MD MDd区别

    MT mutithread Static 多线程库 编译器会从运行时库里面选择多线程静态连接库来解释程序中的代码 即连接LIBCMT lib库 MTd mutithread debug Static 多线程调试版 连接LIBMITD lib