当前位置: 首页 > news >正文

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博客

相关文章:

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

目录 1. 基础概念 2. 直观感受一下静态编译和动态编译的体积与依赖项目 3. VS运行时库包含哪些主要文件&#xff08;从VS2015起&#xff09; 4. 动态库和静态库混用的情况 5. 感谢清单 1. 基础概念 所谓的运行时库&#xff08;Runtime Library&#xff09;就是WINDOWS系统…...

Golang | Leetcode Golang题解之第451题根据字符出现频率排序

题目&#xff1a; 题解&#xff1a; func frequencySort(s string) string {cnt : map[byte]int{}maxFreq : 0for i : range s {cnt[s[i]]maxFreq max(maxFreq, cnt[s[i]])}buckets : make([][]byte, maxFreq1)for ch, c : range cnt {buckets[c] append(buckets[c], ch)}an…...

零信任如何增强网络物理系统 (CPS) 安全性

远程访问对于管理关键基础设施至关重要&#xff0c;因为它允许企业优化和扩展运营并保持效率。然而&#xff0c;它也带来了许多安全漏洞&#xff0c;而且随着连接设备数量的增加&#xff0c;这些漏洞只会越来越多。 到 2025 年&#xff0c;企业和消费者环境中的物联网设备数量…...

V3D——从单一图像生成 3D 物体

导言 论文地址&#xff1a;https://arxiv.org/abs/2403.06738 源码地址&#xff1a;https://github.com/heheyas/V3D.git 人工智能的最新进展使得自动生成 3D 内容的技术成为可能。虽然这一领域取得了重大进展&#xff0c;但目前的方法仍面临一些挑战。有些方法速度较慢&…...

计算机网络期末复习真题(附真题答案)

前言&#xff1a; 本文是笔者在大三学习计网时整理的笔记&#xff0c;哈理工的期末试题范围基本就在此范畴内&#xff0c;就算真题有所更改&#xff0c;也仅为很基础的更改数值&#xff0c;大多跑不出这些题&#xff0c;本文包含简答和计算等大题&#xff0c;简答的内容也可能…...

Unity 的 UI Event System 是一个重要的框架

Unity 的 UI Event System 是一个重要的框架&#xff0c;用于处理用户界面中的输入事件。以下是它的主要特点和功能&#xff1a; 1. 事件管理 UI Event System 负责捕获和管理来自用户的输入事件&#xff0c;如鼠标点击、触摸、键盘输入等。 2. 事件传播 事件通过层次结…...

第十三章 集合

一、集合的概念 集合&#xff1a;将若干用途、性质相同或相近的“数据”组合而成的一个整体 Java集合中只能保存引用类型的数据&#xff0c;不能保存基本类型数据 数组的缺点&#xff1a;长度不可变 Java中常用集合&#xff1a; 1.Set(集):集合中的对象不按特定方式排序&a…...

子非线程池中物

线程池&#xff0c;又好上了 有任务队列 任务要处理就直接放到里面 预先创建好线程&#xff0c;本质上也是一个生产消费模型 线程池真是麻烦啊 我们可以直接沿用之前写过的代码&#xff0c;Thread.hpp: #pragma once #include <iostream> #include <functional&…...

Unraid的cache使用btrfs或zfs?

Unraid的cache使用btrfs或zfs&#xff1f; 背景&#xff1a;由于在unraid中添加了多个docker和虚拟机&#xff0c;因此会一直访问硬盘。然而&#xff0c;单个硬盘实在难以让人放心。在阵列盘中&#xff0c;可以通过添加校验盘进行数据保护&#xff0c;在cache中无法使用xfs格式…...

微服务实战——平台属性

平台属性 中间表复杂业务 /*** 获取分类规格参数&#xff08;模糊查询&#xff09;** param params* param catelogId* param type type"base"时查询基础属性&#xff0c;type"sale"时查询销售属性* return*/ Override public PageUtils listByCatelogId…...

半监督学习与数据增强(论文复现)

半监督学习与数据增强&#xff08;论文复现&#xff09; 本文所涉及所有资源均在传知代码平台可获取 文章目录 半监督学习与数据增强&#xff08;论文复现&#xff09;概述算法原理核心逻辑效果演示使用方式 概述 本文复现论文提出的半监督学习方法&#xff0c;半监督学习&…...

css3-----2D转换、动画

2D 转换&#xff08;transform&#xff09; 转换&#xff08;transform&#xff09;是CSS3中具有颠覆性的特征之一&#xff0c;可以实现元素的位移、旋转、缩放等效果 移动&#xff1a;translate旋转&#xff1a;rotate缩放&#xff1a;scale 二维坐标系 2D 转换之移动 trans…...

SQL进阶技巧:统计各时段观看直播的人数

目录 0 需求描述 1 数据准备 2 问题分析 3 小结 如果觉得本文对你有帮助&#xff0c;那么不妨也可以选择去看看我的博客专栏 &#xff0c;部分内容如下&#xff1a; 数字化建设通关指南 专栏 原价99&#xff0c;现在活动价39.9&#xff0c;十一国庆后将上升至59.9&#…...

Stream流的终结方法

1.Stream流的终结方法 2.forEach 对于forEach方法&#xff0c;用来遍历stream流中的所有数据 package com.njau.d10_my_stream;import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.function.Consumer; import java.util…...

JavaWeb——Vue组件库Element(4/6):案例:基本页面布局(基本框架、页面布局、CSS样式、完善布局、效果展示,含完整代码)

目录 步骤 基本页面布局 基本框架 页面布局 CSS样式 完善布局 效果展示 完整代码 Element 的基本使用方式以及常见的组件已经了解完了&#xff0c;接下来要完成一个案例&#xff0c;通过这个案例让大家知道如何基于 Element 中的各个组件制作一个完整的页面。 案例&am…...

【c++】 模板初阶

泛型编程 写一个交换函数&#xff0c;在学习模板之前&#xff0c;为了匹配不同的参数类型&#xff0c;我们可以利用函数重载来实现。 void Swap(int& a, int& b) {int c a;a b;b c; } void Swap(char& a, char& b) {char c a;a b;b c; } void Swap(dou…...

R 语言 data.table 大规模数据处理利器

前言 最近从一个 python 下的 anndata 中提取一个特殊处理过的单细胞矩阵&#xff0c;想读入R用来画图&#xff08;个人比较喜欢用R可视化 &#xff09;&#xff0c;保存之后&#xff0c;大概几个G的CSV文件&#xff0c;如果常规方法读入R&#xff0c;花费的时间比较久&#x…...

Java 静态代理详解:为什么代理类和被代理类要实现同一个接口?

在 Java 开发中&#xff0c;代理模式是一种常用的设计模式&#xff0c;其中代理类的作用是控制对其他对象的访问。代理模式分为静态代理和动态代理&#xff0c;在静态代理中&#xff0c;代理类和被代理类都需要实现同一个接口。这一机制为实现透明的代理行为提供了基础&#xf…...

OpenCV C++霍夫圆查找

OpenCV 中的霍夫圆检测基于 霍夫变换 (Hough Transform)&#xff0c;它是一种从边缘图像中识别几何形状的算法。霍夫圆检测是专门用于检测图像中的圆形形状的。它通过将图像中的每个像素映射到可能的圆参数空间&#xff0c;来确定哪些像素符合圆形状。 1. 霍夫变换的原理 霍夫…...

H.264编解码介绍

一、简介 H.264,又称为AVC(Advanced Video Coding),是一种广泛使用的视频压缩标准。它由国际电信联盟(ITU)和国际标准化组织(ISO)联合开发,并于2003年发布。 H.264的发展历史可以追溯到上个世纪90年代。当时,视频压缩技术的主要标准是MPEG-2,但它在压缩率和视频质…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度​

一、引言&#xff1a;多云环境的技术复杂性本质​​ 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时&#xff0c;​​基础设施的技术债呈现指数级积累​​。网络连接、身份认证、成本管理这三大核心挑战相互嵌套&#xff1a;跨云网络构建数据…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望

文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例&#xff1a;使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例&#xff1a;使用OpenAI GPT-3进…...

循环冗余码校验CRC码 算法步骤+详细实例计算

通信过程&#xff1a;&#xff08;白话解释&#xff09; 我们将原始待发送的消息称为 M M M&#xff0c;依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)&#xff08;意思就是 G &#xff08; x ) G&#xff08;x) G&#xff08;x) 是已知的&#xff09;&#xff0…...

Python爬虫(二):爬虫完整流程

爬虫完整流程详解&#xff08;7大核心步骤实战技巧&#xff09; 一、爬虫完整工作流程 以下是爬虫开发的完整流程&#xff0c;我将结合具体技术点和实战经验展开说明&#xff1a; 1. 目标分析与前期准备 网站技术分析&#xff1a; 使用浏览器开发者工具&#xff08;F12&…...

python如何将word的doc另存为docx

将 DOCX 文件另存为 DOCX 格式&#xff08;Python 实现&#xff09; 在 Python 中&#xff0c;你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是&#xff0c;.doc 是旧的 Word 格式&#xff0c;而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

什么是EULA和DPA

文章目录 EULA&#xff08;End User License Agreement&#xff09;DPA&#xff08;Data Protection Agreement&#xff09;一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA&#xff08;End User License Agreement&#xff09; 定义&#xff1a; EULA即…...

Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信

文章目录 Linux C语言网络编程详细入门教程&#xff1a;如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket&#xff08;服务端和客户端都要&#xff09;2. 绑定本地地址和端口&#x…...

MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用

文章目录 一、背景知识&#xff1a;什么是 B-Tree 和 BTree&#xff1f; B-Tree&#xff08;平衡多路查找树&#xff09; BTree&#xff08;B-Tree 的变种&#xff09; 二、结构对比&#xff1a;一张图看懂 三、为什么 MySQL InnoDB 选择 BTree&#xff1f; 1. 范围查询更快 2…...

6️⃣Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙

Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙 一、前言:离区块链还有多远? 区块链听起来可能遥不可及,似乎是只有密码学专家和资深工程师才能涉足的领域。但事实上,构建一个区块链的核心并不复杂,尤其当你已经掌握了一门系统编程语言,比如 Go。 要真正理解区…...

java高级——高阶函数、如何定义一个函数式接口类似stream流的filter

java高级——高阶函数、stream流 前情提要文章介绍一、函数伊始1.1 合格的函数1.2 有形的函数2. 函数对象2.1 函数对象——行为参数化2.2 函数对象——延迟执行 二、 函数编程语法1. 函数对象表现形式1.1 Lambda表达式1.2 方法引用&#xff08;Math::max&#xff09; 2 函数接口…...