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

news2024/11/18 7:30:18

目录

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 once

void 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.coloradmin.cn/o/2178628.html

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

相关文章

【易上手快捷开发新框架技术】nicegui标签组件lable用法庖丁解牛深度解读和示例源代码IDE运行和调试通过截图为证

传奇开心果微博文系列 序言一、标签组件lable最基本用法示例1.在网页上显示出 Hello World 的标签示例2. 使用 style 参数改变标签样式示例 二、标签组件lable更多用法示例1. 添加按钮动态修改标签文字2. 点击按钮动态改变标签内容、颜色、大小和粗细示例代码3. 添加开关组件动…

RFID系统如何革新资产信息数字化管理

在现代企业中&#xff0c;资产管理的有效性直接影响整体运营效率和成本控制。为了应对传统资产管理中存在的诸多挑战&#xff0c;越来越多的公司开始采用RFID系统&#xff0c;以实现资产信息的数字化管理&#xff0c;从而提高资产利用率和管理透明度。 RFID系统的主要优势 高…

【USB】USB1.0、USB1.1、USB2.0、USB3.0、USB4.0介绍及最大速率说明

USB 1.0 and USB 1.1 1995 年&#xff0c;成立了 USB-IF&#xff0c;该组织于次年宣布推出 USB 1.0。USB 1.0 规定的数据速率为 1.5 Mbit/s&#xff08;低带宽或低速&#xff09;&#xff0c;最大输出电流为 5V/500mA。但不幸的是&#xff0c;这个 USB 版本也很少被制造商采用。…

C++ string的基本运用详细解剖

string的基本操作 一.与C语言中字符串的区别二.标准库中的string三.string中常用接口的介绍1.string中常用的构造函数2.string类对象的容量操作函数3.string类对象的访问及遍历操作4.string类对象的修改操作5.string类的非成员函数6.string中的其他一些操作 一.与C语言中字符串…

网页WebRTC电话和软电话哪个好用?

关于WebRTC电话与软件电话哪个更好用&#xff0c;这实际上取决于多个因素&#xff0c;并没有一个绝对的答案。不过&#xff0c;我可以根据WebRTC技术的一些特点&#xff0c;以及与传统软件电话相比的优劣势&#xff0c;为你提供一个清晰的对比。 首先&#xff0c;让我们了解一下…

python画图|放大和缩小图像

在较多的画图场景中&#xff0c;需要对图像进行局部放大&#xff0c;掌握相关方法非常有用&#xff0c;因此我们很有必要一起学习 【1】官网教程 首先是进入官网教程&#xff0c;找到学习资料&#xff1a; https://matplotlib.org/stable/gallery/subplots_axes_and_figures…

uniapp在线打包的ios后调用摄像头失败的解决方法

uniapp在线打包的ios后调用摄像头失败的解决方法 解决方法&#xff1a; 由于未选中打包模块的配置 当你在测试时发现能够正常的开启摄像头&#xff0c;但是当你对其进行在线打包后&#xff0c;发现当你点击启用摄像头时&#xff0c;没有反应&#xff0c;或者是打开是黑屏状态…

STM32F103C8----3-1 LED闪烁(跟着江科大学STM32)

一&#xff0c;电路图 接线图 面包板的的使用请参考&#xff1a;《面包板的使用_面包板的详细使用方法-CSDN博客》 二&#xff0c;目的/效果 2.1 推婉输出 外部供电&#xff08;熄的时间长&#xff09; 2.2 推婉输出 内部供电(亮的时间长) 三&#xff0c;创建Keil项目 详…

无人机之集群控制及应用

一、无人机集群控制 无人机集群控制是指通过先进的通信、导航和控制算法&#xff0c;实现多架无人机之间的协同、协调和高效的任务执行。其关键技术包括&#xff1a; 通信技术&#xff1a;实现无人机之间的实时数据传输和共享&#xff0c;确保集群控制的准确性和稳定性。 路径…

RabbitMQ 高级特性——TTL

文章目录 前言TTL设置消息的 TTL设置队列的 TTL 前言 对于前面讲到的重试机制中&#xff0c;当确认策略为 MANUAL 手动确认的时候&#xff0c;如果消费者出现了程序逻辑错误&#xff0c;那么消息就无法被争取处理&#xff0c;那么就会执行 basicNack 方法&#xff0c;如果我们…

黑马头条day7-app端文章搜索

今天的内容也只是跑了一下 对于具体的实现掌握的很差 仔细看 es 在微服务学的es使用基本忘光了 这里用起来一点都熟悉 重学&#xff01;&#xff01;&#xff01; kafka异步 文章自动构建索引的时候用到了‘’ mongoDB 用来存储用户的搜索记录 遗忘&#xff08;拦截器 j…

【有啥问啥】In-Context Learning(上下文学习):深入解析与应用实践

In-Context Learning&#xff08;上下文学习&#xff09;&#xff1a;深入解析与应用实践 引言 在人工智能与机器学习的浪潮中&#xff0c;In-Context Learning&#xff08;上下文学习&#xff09;作为一种新兴的学习范式&#xff0c;正逐渐崭露头角。与传统的机器学习模型不…

第四届机器人、自动化与智能控制国际会议(ICRAIC 2024)征稿

第四届机器人、自动化与智能控制国际会议&#xff08;ICRAIC 2024&#xff09;由湖南第一师范学院主办&#xff0c;南京师范大学、山东女子学院、爱迩思出版社&#xff08;ELSP&#xff09;协办。 大会将专注于机器人、数字化、自动化、人工智能等技术的开发和融合&#xff0c…

Go实现RabbitMQ 死信队列、优化

死信队列是什么&#xff1f; 如何配置死信队列&#xff1f; go实现死信队列 go使用发布订阅模式改造批量发送消息 【教学内容】 1. 死信队列是什么&#xff1f; 注意&#xff1a;业务队列与死信交换机的绑定是在构建业务队列时&#xff0c;通过参数&#xff08;x-dead-le…

计算机网络基础--认识协议

目录 前言 一、IP地址与端口 二、网络协议 1.网络体系结构框架 2.网络字节序 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 计算机网络涉及非常广泛&#xff0c;这篇文章主要对计算机网络有个认识 提示&#xff1a;以下是本篇文章正文内容&#x…

SNMP和Syslog有啥区别

在网络管理的世界中&#xff0c;SNMP&#xff08;简单网络管理协议&#xff09;和 Syslog&#xff08;系统日志&#xff09;是两种关键技术&#xff0c;它们分别在监控和管理网络设备方面发挥着重要作用。选择合适的工具对于确保网络的高效运行、优化性能和增强安全性至关重要。…

【易上手快捷开发新框架技术】nicegui组件button用法庖丁解牛深度解读源代码IDE运行和调试通过截图为证

传奇开心果微博文系列 前言一、button 组件基本用法1. 最基本用法示例2. 创建带图标按钮 二、button按钮组件样式定制1. 按钮的尺寸调整2. 改变颜色示例3. 按钮的自定义字体大小4. 圆角形状示例5. 自定义边框6. 添加阴影7. 复合按钮8. 浮动按钮9. 可扩展浮动操作按钮QFAB10. 按…

OpenCV视频I/O(14)创建和写入视频文件的类:VideoWriter介绍

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 视频写入器类。 该类提供了用于写入视频文件或图像序列的 C API。 cv::VideoWriter 类是 OpenCV 库中用于创建和写入视频文件的一个类。它提供了…

echarts实现3D柱状图(视觉层面)根据博主改编

https://blog.csdn.net/weixin_57798646/article/details/131067725 这是原贴 在这个基础上我需要实现 一根柱子 代码如下 <!DOCTYPE html> <html lang"en" style"height: 100%"><head><meta charset"utf8"> </hea…

【中间件学习】Nginx快速入门(为了配置一个项目)

-----------------------------本文章借鉴遇见狂神说--------------------------- 一、一个产品出现瓶颈&#xff1f;&#xff1f; 在一个产品刚刚上线的时候&#xff0c;并发量小&#xff0c;用户使用的少&#xff0c;所以在低并发的情况下&#xff0c;一个jar包启动应该就够…