VS开发 - 静态编译和动态编译的基础实践与混用

目录

1. 基础概念

2. 直观感受一下静态编译和动态编译的体积与依赖项目

3. VS运行时库包含哪些主要文件(从VS2015起)

4. 动态库和静态库混用的情况

5. 感谢清单


1. 基础概念

所谓的运行时库(Runtime Library)就是WINDOWS系统给我们实现了C/C++的库函数的功能,提供的.LIB和.DLL文件。

其中.LIB是静态库,假如我们程序用.LIB去链接的话,意味着这个EXE里就包含了C/C++库函数的实现,运行的时候就不需要再依赖目标电脑上的运行库,方便拿到其他电脑跑。缺点呢,就是程序体积大。

.DLL则是动态库,选择动态链接的时候,EXE需要用到C/C++库函数的实现的时候,会去系统里面找相对应的DLL。多个程序也可以共享这一个DLL,带来的好处就是节省EXE的体积,但是拿到其他电脑去的话可能跑不起来,报错说:“找不到XXXXX.DLL”

我们用visual studio开发的时候,在项目属性里面可以看到有4种运行时库可选

运行库名称链接方式其他
MT静态
MTd静态Debug版本
MD动态
MDd动态Debug版本

2. 直观感受一下静态编译和动态编译的体积与依赖项目

用vs新建一个工程,简单写一个hello world的程序。

#include <iostream>
using namespace std;int main()
{cout << "Hello World" << endl;return 0;
}

然后分别用静态生成和动态生成:

由上面两个图片可以清晰地看出来:静态编译体积大,动态编译依赖多

3. VS运行时库包含哪些主要文件(从VS2015起)

库描述MTMTDMDMDd
通用C运行时库libucrt.liblibucrtd.lib

ucrt.lib

ucrtbase.dll

ucrtd.lib

ucrtbased.dll

VC运行库libvcruntime.liblibvcruntimed.lib

vcruntime.lib

vcruntime<version>.dll

vcruntimed.lib

vcruntime<version>d.dll

C++标准库libcpmt.liblibcpmtd.lib

msvcprt.lib

msvcp<version>.dll

msvcprtd.lib

msvcp<version>d.dll

初始化CRT的代码库libcmt.liblibcmtd.libmsvcrt.libmsvcrtd.lib

参考链接:C 运行时 (CRT) 和 C++ 标准库 (STL) .lib 文件 | Microsoft Learn

仔细留意一下【初始化CRT的代码库】,为什么动态生成的依赖库只有lib没有dll,官网说它的dll就是【通用C运行时库】和【VC运行库】的合集。这里有点难理解,也不知道为什么要这么设计呢?希望前辈们多多指教一下。

4. 动态库和静态库混用的情况

假如我们现在EXE使用动态编译,但依赖一个静态编译而成的LIB,可以吗?

试试!首先自己编译一个lib。头文件如下:

#pragma oncevoid StaticHello(); // 定义一个函数

源文件如下:

#include "my_mtd_lib.h"
#include <iostream>
using namespace std;// 实现头文件的函数
void StaticHello()
{cout << "----------" << endl;
}

生成选项用调试版的的静态库MTd

接着在其他工程调用这个LIB

#include <iostream>
using namespace std;#include "../my-mtd-lib/my_mtd_lib.h"
#pragma comment(lib, "../Debug/my-mtd-lib.lib")int main()
{cout << "**********" << endl;StaticHello(); // 调用my-mtd-lib.lib的函数return 0;
}

生成选项用调试版的动态库MDd

点生成报错:

1>libcpmtd.lib(wlocale.obj) : error LNK2005: "public: int __thiscall std::ios_base::flags(void)const " (?flags@ios_base@std@@QBEHXZ) 已经在 msvcprtd.lib(MSVCP140D.dll) 中定义
1>libcpmtd.lib(wlocale.obj) : error LNK2005: "public: __int64 __thiscall std::ios_base::width(__int64)" (?width@ios_base@std@@QAE_J_J@Z) 已经在 msvcprtd.lib(MSVCP140D.dll) 中定义
1>libcpmtd.lib(wlocale.obj) : error LNK2005: "public: __int64 __thiscall std::ios_base::width(void)const " (?width@ios_base@std@@QBE_JXZ) 已经在 msvcprtd.lib(MSVCP140D.dll) 中定义
1>libcpmtd.lib(xlocale.obj) : error LNK2005: "public: int __thiscall std::ios_base::flags(void)const " (?flags@ios_base@std@@QBEHXZ) 已经在 msvcprtd.lib(MSVCP140D.dll) 中定义
1>libcpmtd.lib(xlocale.obj) : error LNK2005: "public: int __thiscall std::basic_streambuf<char,struct std::char_traits<char> >::sputc(char)" (?sputc@?$basic_streambuf@DU?$char_traits@D@std@@@std@@QAEHD@Z) 已经在 msvcprtd.lib(MSVCP140D.dll) 中定义
1>libcpmtd.lib(xlocale.obj) : error LNK2005: "public: __int64 __thiscall std::ios_base::width(__int64)" (?width@ios_base@std@@QAE_J_J@Z) 已经在 msvcprtd.lib(MSVCP140D.dll) 中定义
1>libcpmtd.lib(xlocale.obj) : error LNK2005: "public: __int64 __thiscall std::ios_base::width(void)const " (?width@ios_base@std@@QBE_JXZ) 已经在 msvcprtd.lib(MSVCP140D.dll) 中定义

报的都是同一个错:libcpmtd.libmsvcprtd.lib冲突,有符号重定义。再仔细看是不是很眼熟,刚好是前面 第三部分 表格里面【C++标准库】里面MTd和MDd,跟我们项目的设定一一对应。我对这个报错的理解是:链接阶段,main.obj会找到msvcprtd.lib里面关于cout的符号,也发现my-mtd-lib.lib也带了来自libcpmtd.lib的cout的符号,所以报重定义。

所以一个项目里面像我的例子这样混用两个运行时库,实际上大概率不行,理论上也不好。最优的做法当然是所有依赖都基于同一套运行时库。

5. 感谢清单

这篇文章是受到下面博主的文章指引启发的,感谢前辈的分享

你所不知道的C和C++运行库_vcc++运行库-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/54035.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

爬虫库是什么?是ip吗

爬虫库通常指的是用于网页爬虫&#xff08;Web Scraping&#xff09;开发的代码库或框架&#xff0c;它不是IP地址。以下是关于爬虫库的详细解释&#xff1a; 爬虫库的定义 爬虫库是一些用于简化网络数据抓取过程的工具和框架&#xff0c;通常提供了一系列函数和类&#xff0…

C++面向对象基础

目录 一.作用域限定符 1.名字空间 2.类内声明&#xff0c;类外定义 二.this指针 1 概念 2.功能 2.1 类内调用成员 2.2 区分重名的成员变量和局部变量 2.3链式调用 三.stastic关键字 1.静态局部变量 2 静态成员变量 3 静态成员函数 4 单例设计模式&#xff08;了解…

WPS在表格中填写材料时,内容过多导致表格不换页,其余内容无法正常显示 以及 内容过多,导致表格换页——解决方法

一、现象 1&#xff0c;内容过多导致表格不换页&#xff0c;其余内容无法正常显示 2&#xff0c;内容过多&#xff0c;导致表格换页 二、解决方法 在表格内右击&#xff0c;选择表格属性 在菜单栏选择行&#xff0c;勾选允许跨页断行&#xff0c;点击确定即可 1&#xff0…

【WRF工具】WRF Domain Wizard第二期:服务器中下载及安装

【WRF工具】WRF Domain Wizard第二期&#xff1a;服务器下载及安装 准备WRF Domain Wizard下载及安装WRF Domain Wizard下载WRF Domain Wizard安装添加环境变量&#xff08;为当前用户永久添加环境变量&#xff09;Java环境安装报错-Exception in thread "main" java…

今年Java回暖了吗

今年回暖了吗 仅结合师兄和同学的情况 BG 大多双非本 少部分211本 985硕 去年十月一之前 基本转正都失败 十月一之前0 offer 只有很少的人拿到美团 今年十月一之前 有HC的基本都转正了&#xff08;美团、字节等&#xff09;&#xff0c;目前没有HC的说也有机会&#xff08;…

STM32F1+HAL库+FreeTOTS学习15——互斥信号量

STM32F1HAL库FreeTOTS学习15——互斥信号量 1. 优先级翻转2. 互斥信号量3. 相关API函数&#xff1b;3.1 互斥信号量创建3.2 获取信号量3.3 释放信号量3.4 删除信号量 4. 操作实验1. 实验内容2. 代码实现3. 运行结果 上期我们介绍了数值信号量。这一期我们来介绍互斥信号量 1. 优…

[Docker学习笔记]利用Dockerfile创建镜像

Dockerfile 指令 指令作用from继承基础镜像maintainer镜像制作者信息(可缺省)run用来执行shell命令expose暴露端口号cmd启动容器默认执行的命令entrypoint启动容器真正执行的命令volume创建挂载点env配置环境变量add复制文件到容器copy复制文件到容器workdir设置容器的工作目录…

QT C++ 自学积累 『非技术文』

QT C 自学积累 『非技术文』 最近一段时间参与了一个 QT 项目的开发&#xff0c;使用的是 C 语法&#xff0c;很遗憾的是我之前从来没有接触过 C &#xff0c;大学没有开过这堂课&#xff0c;也没用自己学习过&#xff0c;所有说上手贼慢&#xff0c;到现在为止其实也不是很清楚…

【IOS】申请开发者账号(公司)

目录 申请开发者账号前提 查询/申请D-U-N-S 编号 申请开发者 官网&#xff1a;Apple Developer (简体中文) 申请开发者账号前提 如果是第一次申请建议注册一个新的apple id作为组织的开发者账号。&#xff08;确保apple id的个人信息是真实的&#xff0c;不能是网名或者是…

Chainlit集成LlamaIndex实现知识库高级检索(组合对象检索)

检索原理 对象组合索引的原理 是利用IndexNode索引节点&#xff0c;将两个不同类型的检索器作为节点对象&#xff0c;使用 SummaryIndex &#xff08;它可以用来构建一个包含多个索引节点的索引结构。这种索引通常用于从多个不同的数据源或索引方法中汇总信息&#xff0c;并能…

golang学习笔记19-面向对象(一):面向对象的引入

注&#xff1a;本人已有C&#xff0c;C,Python基础&#xff0c;只写本人认为的重点。 这节开始就是面向对象的内容了&#xff0c;为方便复用结构体等类型&#xff0c;本人定义了一个utils包&#xff0c;用于定义这些类型&#xff0c;之后的文章也会用到&#xff0c;希望读者注意…

Java如何将Object转换成指定Class对象

在Java中&#xff0c;将Object转换为指定类型的Class对象实际上是两个不同概念的操作&#xff1a; 将Object实例转换为特定类型的实例&#xff1a;这通常涉及到类型转换&#xff08;如(MyType) myObject&#xff09;或者通过反射机制&#xff08;Class.cast(Object)&#xff0…

后端开发如何提高项目系统的性能

引言 提高后端PHP开发系统的性能可以从多个维度进行&#xff0c;例如通过代码优化、缓存优化、数据库优化、异步处理和消息队列、服务器优化、内容分发网络&#xff08;CDN&#xff09;的应用以及系统安全性的强化。 本文主要介绍如何通过以上方法对系统进行优化&#xff0c;…

删除搜狗拼音输入法,右键菜单打印及pdf操作

删除搜狗拼音输入法流氓右键菜单打印及pdf操作&#xff1a; 1、注册表分别搜以下字段&#xff0c;全部删除&#xff0c;可用Registry Workshop 方便搜索&#xff1a; {7BCE96FA-77AF-4288-9E16-2388A50EC807} {85212cfd-77ed-4add-8e24-a0a39e3dbfc3} {1BB732FA-391B-4648-BC00…

【TabBar嵌套Navigation案例-新特性页面-介绍图片 Objective-C语言】

一、接下来,我们接着来说这个介绍图片啊, 1.看一下我们的示例程序,在这一块儿,有一些介绍图片, 这个飞镖的盘子,全新娱乐场,疯狂什么玩意儿,这些东西呢,实际上,都是我们的素材啊,在素材里边,Guide里边,我们这儿有一个guide1, Open With External Editor,这张图片…

MobaXterm基本使用 -- 服务器状态、批量操作、显示/切换中文字体、修复zsh按键失灵

监控服务器资源 参考网址&#xff1a;https://www.cnblogs.com/144823836yj/p/12126314.html 显示效果 MobaXterm提供有这项功能&#xff0c;在会话窗口底部&#xff0c;显示服务器资源使用情况 如内存、CPU、网速、磁盘使用等&#xff1a; &#xff08;完整窗口&#xff0…

经典sql题(十四)炸裂函数的恢复

下面是一个关于 SELECT 语句的例子&#xff0c;该示例展示了如何使用 CONCAT_WS 和 COLLECT_LIST 函数来处理炸裂之后学生成绩的数据。假设我们有一个名为 test 的表&#xff0c;结构如下&#xff1a; 表结构 test student_idstudent_nameclassscore1AliceClass1901AliceClas…

蓝桥杯—STM32G431RBT6(RTC时钟获取时间和日期)

一、RTC是什么&#xff0c;有什么用&#xff1f; 在 STM32 中&#xff0c;RTC&#xff08;Real-Time Clock&#xff0c;实时时钟&#xff09;主要有以下作用&#xff1a; 时间保持&#xff1a;即使在系统断电情况下&#xff0c;也能持续记录时间。&#xff08;需要纽扣电池供电…

【2.使用VBA自动填充Excel工作表】

目录 前言什么是VBA如何使用Excel中的VBA简单基础入门控制台输出信息定义过程&#xff08;功能&#xff09;定义变量常用的数据类型Set循环For To 我的需求开发过程效果演示文件情况测试填充源文件测试填充目标文件 全部完整的代码sheet1中的代码&#xff0c;对应A公司工作表Us…

简易CPU设计入门:取指令(一),端口列表与变量声明

取指令这一块呢&#xff0c;个人觉得&#xff0c;不太好讲。但是呢&#xff0c;不好讲&#xff0c;我也得讲啊。那就尽量地讲吧。如果讲得不好的话&#xff0c;那么&#xff0c;欢迎大家提出好的意见&#xff0c;帮助我改进讲课的质量。 首先呢&#xff0c;还是请大家去下载本…