网站首页 > 技术 正文

编译dll时,如何不依赖c++运行库

唐哲 2019-08-11 10:13:34 技术 7010 ℃ 1 评论

用VC编译的DLL如果依赖VC运行库,分发时如果目标系统不带对应版本的VC支行库,将导致DLl调用失败,在编译时应设置不依赖VC运行库:

在C/C++/Code Generation的Runtime Library中选择Multi-threaded(/MT)  Release配置或Multi-threaded Debug(/MTd) Debug配置就可以编译出不依赖VC运行库的DLL了。

image.png

image.png

在vs中,项目属性 -》C/C++ -》代码生成 -》运行库 选项内有四个选项:多线程(/MT)、多线程调试(/MTd)、多线程DLL(/MD)、多线程调试DLL(/MDd)。这个设置代表什么意思?四个选项又是什么意思,有什么区别?接下来详细讨论。

先奉上一个写得非常详细的博客链接:你所不知道的C和C++运行库,这个文章中写得非常详细,本文也主要参考了这篇文章。

还有这篇C Runtime Library 的来历。


1. 何为C运行库、C++标准库

C标准定义了一系列常用函数,成为C库函数。C标准仅仅定义了函数原型,没有提供实现。


因此这个任务留给了各个支持C语言标准的编译器。每个编译器通常实现了标准C的超集,称为C运行时库(C Run-Time Library)。

C run-time Library包含了C程序运行的最基本和最常用的函数,没有C run-time Library则main()函数不会被调用,exit()也不能被响应。C运行库与平台相关。


到了C++的世界,有了另外一个概念:Standard C++ Library。因为C++是C的超集,所以Standard C++ Library包括了C run-time Library和STL。

VC++针对C++ 加入的Standard C++ Library主要包括:libcp.lib、libcpmt.lib、msvcprt.lib。


在windows环境下,VC++提供的C Run-Time Library又分为动态运行时库和静态运行时库。

动态运行时库主要是DLL库文件msvcrt.dll(vc 6.0,之后是msvcr100.dll等),静态运行时库对应的主要文件是libc.lib(Single thread static library, retail version) 、LIBCMT.LIB (Multithread static library, retail version) 。msvcrt.dll运行时库提供几千个C函数,包括printf,程序运行时很大部分时间都是在这些运行库中。到底使用哪些库取决于你的编译器及编译选项:/MT、/MTd、/MD、/MDd。


动态运行时库(MD/MDd)

动态运行时库主要包括:

·DLL库文件:msvcrt.dll(或 MSVCRTD.DLL for debug build)

·对应的Import Library文件:MSVCRT.LIB(或 MSVCRTD.LIB for debug build)

上面为vc6.0编译器用到的库,在vs中为msvcr100.dll等


DLL版本名称根据编译器不同而不同,我们可以从名称上加以分辨。

VC6.使用的CRT库的DLL版本在MSVCRT.DLL中实现, 对应调试版本为MSVCRTD.LIB。

VC2005使用的CRT库的DLL版本在MSVCR80.DLL中实现,对应调试版本为MSVCR80.DLL。

VC2008使用的CRT库的DLL版本在MSVCR90.DLL中实现,对应调试版本为MSVCR90D.DLL。

VC2010使用的CRT库的DLL版本在MSVCR100.DLL中实现,对应调试版本为MSVCR100D.DLL。


静态运行时库(MT/MTd)

静态运行时库(release版)对应的主要文件包括:

LIBC.LIB(Single thread static library, retail version)

LIBCMT.LIB(Multithread static library, retail version)

不同编译器实现的库名都相同,都为libcmt.lib,调试版为libcmtd.lib。


C++标准库

对于C++标准库中的IO流和STL,VC6.0、VC2005、VC2008和VC2010也提供了DLL版本和LIB版本。

LIB版均实现在libcpmt.lib中,对应的调试版本为libcpmtd.lib。

不同版本的编译器实现的DLL也不相同。

  VC6.使用的C++类库的 DLL版本在MSVCP60.DLL中实现, 对应调试版本为MSVCP60D.LIB。

  VC2005使用的C++类库的DLL版本在MSVCP80.DLL中实现,对应调试版本为MSVCP80.DLL。

  VC2008使用的C++类库的 DLL版本在MSVCP90.DLL中实现,对应调试版本为MSVCP90D.DLL。

  VC2010使用的C++类库的DLL版本在MSVCP100.DLL中实现,对应调试版本为MSVCP100D.DLL。


编译器中运行库设置

/MT、/MTd、/MD、/MDd各选项区别

MT选项:链接LIB版的C和C++运行库。在链接时就会在将C和C++运行时库(LIBCMT.LIB、LIBC.LIB)集成到程序中,程序体积会变大。

MTd选项:LIB的调试版。

MD选项:使用DLL版的C和C++运行库,这样在程序运行时会动态的加载对应的DLL,程序体积会减小,缺点是在系统没有对应DLL时程序无法运行(需添加MSVCPxx.DLL、MSVCRxx.DLL)。

MDd选项:表示使用DLL的调试版。

带T的链接静态库lib;带D链接动态库dll;带d为调试版本,库名加d


如何选择运行库

先看几个错误:

error LNK2038

image.png

error LNK2005

image.png

当引用的库和当前项目设置的运行库不一致时,会出现error LNK2038: 检测到“RuntimeLibrary”的不匹配项…

当引用的库或当前的库有一个使用/MT时,会出现error LNK2005:…

所以若当前VC项目不引用其他VC项目,则可以使用任意一种运行库选项;若需要引用其他VC项目,则所有的项目都需设置运行库选项为/MD或/MDd。


已有1位网友发表了看法

  • 访客

    访客  评论于 [2019-09-08 08:43:15]  回复

    学习了

欢迎 发表评论:

请填写验证码
«    2024年4月    »
1234567
891011121314
15161718192021
22232425262728
2930
搜索
网站分类
站点信息
  • 文章总数:89
  • 页面总数:1
  • 分类总数:4
  • 标签总数:19
  • 评论总数:97
  • 浏览总数:617505
控制面板
您好,欢迎到访网站!
  查看权限
唐哲 - 和仲科技