Visual Studio如何实现.exe免安装免DLL运行[动态链接库--->>>静态链接库]


前言

目的:Visual Studio编译生成的.exe可执行文件,可以免安装免DLL在其他电脑直接运行。换句话说,将执行程序的动态链接库改成静态链接库
测试程序:测试程序分为 有MFC使用无MFC使用
方法:就是在编译可执行文件的时候,将可执行文件需要调用的对应动态链接库中的部分提取出来,链接到可执行文件中去,使可执行文件在运行的时候不依赖动态链接库。


一. 什么是程序库?

程序库(library),一个写好的现有的,成熟的,可供使用的各种标准程序、子程序、文件以及它们的目录等信息的代码集合。每个应用程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常。比如你经常使用的STL(Standard Template Library)也是库,有了STL你才能方便地使用std::string、std::cout这些类。

本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存,被别的程序调用执行。C++的库有两种:静态库和动态库。将一个程序编译成可执行文件一般经过 预编译–>编译–>链接 这几个过程,而静态库与动态库的区别主要体现在链接这个过程。

1. 静态库:

在链接阶段,会将编译的目标文件.obj 与引用到的库.lib 一起链接打包到可执行文件exe(也称为目标代码)中,程序运行时将不再需要该静态库。

因此最终链接成的可执行文件(.exe)体积较大。在Windows中一般以.lib为后缀名,在Linux中一般以.a为后缀名。

2. 动态库:

在链接阶段,动态库.dll并没有真正被连接到目标代码中,只是将这个动态库的声明链接到目标代码中(这样程序运行时才知道怎样使用这个动态库),动态库.dll依然是独立存在的,只有在程序运行是才会将.dll载入到内存中被程序调用。因此程序运行时必须要有这个动态库且放在正确的路径中。

因此最终链接成的可执行文件(.exe)体积较小。在Windows中一般以.dll为后缀名,在Linux中一般以.so为后缀名。

3. 两者区别:

特点静态库动态库
链接时机在编译的链接阶段完成的推迟到程序运行的时期
运行过程与库的关系程序在运行时与静态库再无关系程序在运行时与动态库库需要一直存在且路径正确
是否链接到可执行文件静态库被链接合成一个可执行文件动态库不会被链接到可执行文件中
目标文件大小较大较小
内存占用度占用内存。如果多个程序使用了同一个静态库,每一个程序者会包含这个静态库节约内存。如果多个程序使用了同一个动态库,可以实现进程之间的资源共享(因此动态库也称为共享库)
程序移植移植方便移植不太方便,需要所有动态库的头文件
程序升级程序升级麻烦,需要下载整个程序进行升级程序升级更简单,只需要升级某个DLL或某个程序,下载一个升级包即可
编译出的文件ProjectName.libProjectName.lib+ProjectName.dll, 这里的ProjectName.lib与静态库的.lib文件不同,这只是一个导入库,只包含了地址符号表等,以便调用方的程序能找到对应的函数,真正的库文件是ProjectName.dll

二. 配置方法

根据上面介绍的程序库的差别,我们可以选择不同的编译方式,如果选择静态编译的方式,配置方法如下:

1. debug下的配置方法

(1)项目 -> 配置属性->常规->MFC的使用 :在静态库中使用MFC(如果有使用MFC)。
  (Project—Properties—Configuration Properties—General—Use of MFC—Use MFC in a Static Library
(2)项目 -> 配置属性->C/C+±>代码生成->运行库 :选择 多线程调试(/MTd)。
  (Project—Properties—Configuration Properties—C/C++—Code Generation—Runtime Library—Multi-threaded(/MTd)
编译时,选择的是debug,win32
  然后执行编译生成.exe,在该工程目录下的debug文件中,找到该.exe文件,即可在其他电脑运行。
  debug方式生成的.exe文件会比较大,因为它包含了一些调试用的信息。

2. release下的配置方法

(1)项目 -> 配置属性->常规->MFC的使用 :在静态库中使用MFC(如果有使用MFC)。
  (Project—Properties—Configuration Properties—General—Use of MFC—Use MFC in a Static Library
(2)项目 -> 配置属性->C/C+±>代码生成->运行库 :选择 多线程(/MT)。
  (Project—Properties—Configuration Properties—C/C++—Code Generation—Runtime Library—Multi-threaded(/MT)
  编译时,选择的是release(这个选择项在工具栏的debug下拉列表中),win32。
  然后执行编译生成方案,在该工程目录下的release文件中,找到该.exe文件,即可在其他电脑运行。

三. 补充说明(Runtime Library、MT、MTd、MD、MDd)

1. 什么是Runtime Library?

CRT原先是指Microsoft开发的C Runtime Library,用于操作系统的开发及运行。后来在此基础上开发了C++ Runtime Library,所以现在CRT是指Microsoft开发的C/C++ Runtime Library。在VC的CRT/SRC目录下,可以看到CRT的源码,不仅有C的,也有C++的。

CRT原先的目的就是支持操作系统的运行。因为Windows操作系统除汇编部分外,都是用C/C++编写的,所以内核及许多关键服务都在CRT上运行(它们都采用dll技术动态链接)。此外,用 VC编写的C/C++程序也用到它们(可以动态链接,也可以静态链接,前者运行时需要系统中已安装CRT的dll,后者不需要)。可以说,CRT就是 Microsoft编写Windows时使用的低层类库。然后,它又被当作C++标准库的一个实现包含在了VC系列中;我们在VC中使用的C++标准库,其实就是CRT的一个真子集(少了C++标准所不包含的代码,特别是大量的低层C代码)

确切地说运行时库指的就是对这些底层的基础功能实现的动态库(Dll),运行时库和普通的Dll一样,只有程序用到了它才会被加载,没有程序使用的时候不会驻留内存的。话虽如此,但有多少系统的东西说不定也是用C写的,这些东西的存在就使C运行时库存在于内存中了,所以运行时库几乎总是需要的。虽然说运行时库应该是动态库,但习惯上我们把与动态运行时库相同代码编译出来的静态库也称为运行时库,因此VC++下的运行时库有ML、MLd、MT、MTd、MD、MD六种。

2. MT、MTd、MD、MDd、(ML、MLd 已废弃)的区别与原理

我们可以在Properties->Configuration Properties->C/C+±>Code Generation->Runtime Library中设置采用的运行时库的类型。

VC++中有六种Runtime Library的类型:

类型含义对应的库名称
Single-Threaded(/ML)Release版的单线程静态库libc.lib (VS2003后被废弃)
Single-Threaded Debug(/MLd))Debug版的单线程静态库libcd.lib (VS2003后被废弃)
Multi-threaded (/MT)Release版的多线程静态库libcmt.lib
Multi-threaded Debug(/MTd)Debug版的多线程静态库libcmtd.lib
Multi-threaded DLL (/MD)Release版的多线程动态库msvcrt.lib+msvcrtxx.dll
Multi-threaded DLL Debug(/MDd)Debug版的多线程动态库msvcrtd.lib+msvcrtxxd.dll

你可以在VS的安装目录下找到这些库文件,如我的VS2019安装在C:\Program Files (x86)\Microsoft Visual Studio\2019,则可以在C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.26.28801\lib\中分别找到对应32位和64位的libcmt.lib、libcmtd.lib、msvcrt.lib、msvcrtd.lib库。

(1). 静态链接的单线程库(废弃)

静态链接的单线程库只能用于单线程的应用程序, C 运行时库的目标代码最终被编译在应用程序的二进制文件中。通过 /ML 编译选项可以设置 Visual C++ 使用静态链接的单线程库。

(2). 静态链接的多线程库

静态链接的多线程库的目标代码也最终被编译在应用程序的二进制文件中,但是它可以在多线程程序中使用。通过 /MT 编译选项可以设置 Visual C++ 使用静态链接的多线程库。

(3). 动态链接的运行时库

动态链接的运行时库将所有的 C 库函数保存在一个单独的动态链接库 MSVCRTxx.DLL 中, MSVCRTxx.DLL 处理了多线程问题。使用 /MD 编译选项可以设置 Visual C++ 使用动态。

使用此选项编译的应用程序静态链接到MSVCRT.lib。该库提供了一层代码,使链接程序能够解析外部引用。实际的工作代码包含在MSVCR版本号.DLL中,该文件必须在运行时可用于与MSVCRT.lib链接的应用程序。链接时将按照传统VC链接dll的方式将运行时库MSVCRxx.DLL的导入库MSVCRT.lib链接,在运行时要求安装了相应版本的VC运行时库可再发行组件包(当然把这些运行时库dll放在应用程序目录下也是可以的)。 因/MD和/MDd方式不会将运行时库链接到可执行文件内部,可有效减少可执行文件尺寸。当多项目以MD方式运作时,其内部会采用同一个堆,内存管理将被简化,跨模块内存管理问题也能得到缓解。

/MDd 、 /MLd 或 /MTd 选项使用 Debug runtime library( 调试版本的运行时刻函数库 ) ,与 /MD 、 /ML 或 /MT 分别对应。 Debug 版本的 Runtime Library 包含了调试信息,并采用了一些保护机制以帮助发现错误,加强了对错误的检测,因此在运行性能方面比不上 Release 版本。

  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值