(您可以在底部找到执行摘要或 TL;DR)
重要提示:此答案仅指官方 Microsoft 工具链,而不是已知链接到msvcrt.dll
. 但我怀疑微软是否会倾向于支持该工具链;)
简短的回答:不!
甚至不要尝试使用 Visual C++ 2010 来完成这项任务。
有一个官方和受支持的方法:使用独立的 WDK,如果您需要您的应用程序链接到msvcrt.dll
!
您永远不应尝试使用与 CRT 头文件和库不匹配的编译器工具链。按照 Microsoft 的意图使用工具链,而不是您创建的拼凑而成。不要混搭。使用 Microsoft 提供给您的内容。但是使用它(不要害怕 FUD)。
可用于链接的最新 WDK msvcrt.dll
(7600.16385.1) 使用cl.exe
版本 15.00.30729.207。这大致对应于 Visual C++ 2008 附带的编译器!以后的 WDK 将链接到他们需要的 Visual C++ 版本的 CRT 。
msvcrt.dll
您会发现,Windows XP 或 Windows 7并不是Visual C++ 6.0(甚至是最新版本的 VC6)中包含的原始DLL。
这也已在其他答案中正确说明。那里没有惊喜。
但是,与其他答案所暗示的相反msvcrt.dll
,您将在现代系统上找到的VC6 CRT 允许链接到原始 VC6 CRT 的程序继续工作。即使在今天。这是一份合同。并且升级msvcrt.dll
到系统 DLL 进一步验证了该合同。
一点历史背景
Microsoft 内部使用的工具链有点类似于在 Windows 8 WDK 之前提供的 WDK。我将专门写这些并统一使用术语 WDK(或独立 WDK),即使在 Vista WDK 之前它们被称为 DDK。
来自OSR的好人,他们似乎可以访问 Windows 源代码或可以访问的人,在几年前我参加的一次研讨会上证实,WDK 曾经是内部使用的工具链的精简版本,用于围绕时间(〜2005年)。类似的提示可以从 MSFT 自己的 Larry Osterman和Alex Ionescu 在 tinykrnl 上的早期作品中找到,最近版本的“Windows Internals”的合著者。BCZ 可能暗指build -cZ
,这是我在此处描述的 WDK 的常用调用。
在这种情况下有趣的原因是:所有独立的 WDK 都允许您创建msvcrt.dll
默认链接的可执行文件。独立的WDKmsvcrt.dll
是CRT,就像 Visual C++ 2010 的.msvcr100.dll
还应注意,工具链与 Visual Studio 工具链一起更新。例如,在 3790.1830 WDKcl.exe
报告中,它与 Visual C++ 2003 大致相当:
C:\WINDDK\3790.1830\bin\x86>cl /version
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.4035 for 80x86
Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.
对于 6001.18002 WDK(最新支持 Windows 2000!)与 Visual C++ 2005 大致相当:
C:\WINDDK\6001.18002\bin\x86\x86>cl/version
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.278 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
对于 7600.16385.1 WDK,它与 Visual C++ 2008 相当。
独立 WDK
WDK 版本从 XP 开始,直到(包括)Windows 7 SP1 不需要 Visual Studio。他们带有自己的工具链。
Windows XP 之前的版本需要 Visual C++ 来构建任何东西。如果我没记错的话,VC6 适用于 Windows 2000 DDK。
从 Windows 8 WDK 开始的版本再次需要 Visual C++,并且与它的集成比以往任何时候都更加紧密(包括向导,甚至用于调试和某些驱动程序特定任务的扩展)。这也是为什么当您使用各自的 WDK 时,它们会链接到各自工具链的 CRT。
在独立的 WDK 时代,人们尝试使用 Visual Studio 来封装 WDK 构建过程并非闻所未闻——这正是 DDKWizard 和VisualDDK的真正原因。有些人甚至使用了微软推荐的不受支持的方法,并使用Visual Studio 工具链构建了他们的驱动程序。那些不受支持的方法大致相当于您正在尝试的方法。所以不要。
build.exe
无论如何,使用 WDK和sources
等等的构建过程makefile
是麻烦和限制的。例如,要从当前目录或其父目录之外的任何源文件构建,您必须编写自己的 NMake 规则。毕竟build.exe
是基于 NMake 的构建的包装器。您的本地makefile.inc
将包含在 WDK/DDK 提供的全局中。
为什么msvcrt.dll
官方支持链接到
如前所述,msvcrt.dll
独立 WDK 支持链接。
这也很好。事实上,文件中的USE_MSVCRT=1
语句sources
正是具有这种效果。见这里。引用 7600.16385.1 WDK 文档:
USE_MSVCRT
使用USE_MSVCRT
宏来指示构建实用程序使用 DLL 中的多线程运行时库进行构建。
句法
USE_MSVCRT = 1
[...]
注意 您永远不应该列出Msvcrt.lib
或Msvcrtd.lib
在TARGETLIBS
. 但是,您可以Ntdll.lib
在TARGETLIBS
.
如果微软不支持这条路径,为什么还要提供呢?正确,他们不会!
事实上,WDK (XP..7 SP1) 一直在使用系统 DLL msvcrt.dll
作为其 CRT。
注意事项
主要有一个警告。SEH 的实现方式随着时间的推移随着更新的 Visual C++ 版本而改变。由于来自独立 WDK 的工具链与特定的 Visual C++ 版本密切对应,因此它们继承了各自的 SEH 处理。
例如,当您使用 Windows 7 SP1 WDK 以 Windows 7 为目标时USE_MSVCRT=1
,它会静态导入_except_handler4_common
. 例如,该功能在 Windows Server 2003 上不可用。因此,尝试在目标版本之前的 Windows 版本上运行此类应用程序可能会失败。因此,在这种情况下,您正在冒险进入“不受支持的领域”,并且所有免责声明都适用。但是,您可以选择使用此处概述的方法,即链接到msvcrt_win2000.obj
和(在 Vista 和 7 WDK 中可用)来实现您想要的(二进制)向后兼容性级别msvcrt_winxp.obj
。msvcrt_win2003.obj
好吧,另一方面,如果您决定设置,WINVER=0x0601
您也不应该惊讶地发现生成的可执行文件从 kernel32.dll(或其他系统 DLL)导入函数,而这些函数在 Windows XP 上不可用。那么为什么期望不同的语义msvcrt.dll
呢?
作为另一个旁注:即使已检查的构建(通常被认为对应于调试构建)也链接到msvcrt.dll
,而不是其调试版本对应!因为“已检查”是指保留断言的事实;它不是指 CRT 的特定配置,例如“发布”或“调试”。假设msvcrt.dll
在独立 WDK 中无法进行调试构建意味着它在某种程度上不是那些 WDK的C 运行时,这是对检查构建的含义的简单误解。
还有一个小警告。msvcrt.dll
例如,如果您使用Windows 7 WDK 来实现与. 所以不要指望它支持发布时不可用的功能。
系统DLL:msvcrt.dll
msvcrt.dll
几年前被提升为系统 DLL 的状态,这意味着它与其他 Visual C++ CRT 不同,它包含在系统中(并且可以从字面上依赖),您需要为其安装相应的可再发行包。这也是另一个答案中引用的 Raymond Chen 博客文章的要点。
由于独立的 WDK (XP..7 SP1) 默认链接到msvcrt.dll
作为它们的 CRT,因此没有反对它的客观论据。当然意见不一。
回答”
不幸的是,自从我第一次发表评论以来,这个答案已经发生了很大变化,使 FUD 长期存在,并试图从所谓的权威来源中断章取意地引用。它还链接到原始 (MSFT) 来源 - 经过仔细检查 - 不支持它们所链接的支持声明。
几年前,微软的 Raymond Chen 曾在博客上发表过这篇文章。从他的博客Windows 不是 Microsoft Visual C/C++ 运行时交付渠道:
一个与所有版本的 Visual C++ 兼容的 DLL 是维护的噩梦……在某些时候,决定放弃并声明它是操作系统 DLL,仅供操作系统组件使用。
强调我的。再想一想,你真的在写 Windows 自带的东西吗?将支持的文件添加到您的安装程序或链接 CRT 的静态版本,而不是依赖于微软十多年前在编译器兼容性方面放弃的系统组件,是否有那么难?
好的,所以 2010 年 2 月是十多年前(写这个答案的时间:2016 年 3 月)?因为那是 7600.16385.1 WDK 的发布日期,它正式支持链接到msvcrt.dll
.
Raymond 的其他声明可能与微软最初的意图相符,但他甚至承认他们放弃了这一点,并将其提升为系统 DLL。
此外,将真正古老的历史 (Windows 9x) 与支持使用甚至不支持 Windows 9x 的独立 WDK 的建议混合在一起是非常不诚实的。Raymond 描述的历史背景是 W2K 之前和非 NT。我上面描述的背景是指 Windows 的 NT 血统,我只知道独立的 DDK/WDK(和更新的)从实践中,所以我不知道在此之前它是如何或应该是什么。
话虽如此:不要将他的博客与 Microsoft 的官方文档混淆,尽管在他的博客上可以找到很多珍品,而且我多年来一直是狂热的读者。
尽管那是十多年前的事了,但msvcrt.dll
Windows 2000 (SP4) 中的版本信息显示:
Description: Microsoft (R) C Runtime Library
Product: Microsoft (R) Visual C++
Prod version: 6.10.9844.0
File version: 6.10.9844.0
...与雷蒙德的介绍性声明相反。
只有在 Windows XP 中才会更改为:
Description: Windows NT CRT DLL
Product: Microsoft« Windows« Operating System
令人惊讶的是,仍有多少人否认这一决定。
在之前的一些评论之后,可以公平地假设这完全是针对我的。
好吧,我并不否认发布 Windows 8 WDK 所做出的决定。但这并没有“取消发布”官方支持链接的独立 WDK,msvcrt.dll
也没有“取消记录”可以在其各自的官方文档中找到的内容。
嘿,如果您处于奢侈的位置,只需要支持 Windows 7 或 8 及更新版本,或者类似的东西,我觉得很酷。但是,我也必须支持早期的 Windows 版本,因此我将充分利用微软为这些 Windows 版本提供的官方工具。可以是集成了适当 SDK 的 Visual C++ 2005,也可以是独立的 WDK。
那些人给“Visual C++ 产品团队带来了极大的悲痛”
该声明引用了 Raymond Chen 的上述博客文章,但将 Raymond 的声明脱离了上下文,特别是脱离了时间上下文。悲伤是由于人们尝试了提问者想要做的事情 - 更糟糕的是:触及msvcrt.dll
. 那是在 W2K 之前。它不是(也不会是)由使用官方工具链(如 Microsoft 的独立 WDK)引起的。
现代版本的 Windows 中的 msvcrt 版本从未在相应版本的 Windows SDK 中提及。
虽然现代应该是合格的,但“Windows SDK”的使用表明它指的是从“平台 SDK”重命名后的所有 Windows SDK。我倾向于欣然相信这一点。但是海报忽略了独立的 Windows WDK(以及在此之前的 DDK),它们不仅提到它,而且还msvcrt.dll
用作它们的 CRT。它们是Microsoft 的官方工具链,针对内核和用户模式开发。
Microsoft 使用可能会或可能不会公开的当前工具链更新 CRT DLL(例如,在发布 Windows Media Player 补丁时)。
这是正确的。msvcrt.dll
不断更新,因为它已被提升为系统 DLL。这就是使用 WDK 时可以依赖的合同。他们不会仅仅因为他们正在修补msvcrt.dll
.
您可以指望他们没有使用古老的 WDK 编译器和库在 Windows 中构建 msvcrt DLL
我什至不确定这一点,但 2010 年的官方工具链并不是我称之为古老的东西。此外,由于微软同时放弃了对 XP 和 2003 的支持,他们只需要支持 Vista 及更高版本。使用最新的 Visual C++ 版本肯定会更容易,它直接为从 Windows 8 开始的 WDK 提供编译器和工具。
(为什么古老?因为WDK团队也不喜欢人们使用他们的编译器链接msvcrt,并删除了8.0版本的漏洞以阻止那些“聪明”的人)。
哦,真的,Doron 真的在链接的论坛帖子中这么说吗?好吧,不:
win7 wdk 构建部署成功,因为您链接到 Windows CRT (msvcrt.dll)。我们不想让第 3 方再这样做
了,所以我们在 win8 wdk 中删除了该功能。它仍然适用于向后兼容。虽然它可能会成功部署,但可能会有 whck 徽标检查以确保您使用正确的 CRT
(强调我的)
该声明是关于微软改变立场的“政治决定”(也是官方决定)。“不再”实际上意味着这仅在 Windows 8 WDK 中发生了变化。第一个与 Visual C++ 再次集成的现代 WDK(自 Windows 2000 DDK 起)。因此,由于 WDK 已从独立工具链降级为与给定 Visual C++ 版本集成的扩展,因此新要求一点也不奇怪。
顺便说一句,基于 Windows 8 WDK 和更新版本的争论也是不诚实的,因为有关msvcrt.dll
用作 CRT 的独立 WDK 的建议早于该政策更改。将导致升级为msvcrt.dll
系统DLL的历史与升级后的时代混为一谈也是不诚实的。
词汇表
- CRT == C/C++ 运行时
- 3790.1830 == Windows Server 2003 Service Pack 1 (SP1) 驱动程序开发工具包 (DDK)
- 6001.18002 == 适用于 Windows Server 2008/Vista 的 Windows Driver Kit SP1
- 7600.16385.1 == Windows Driver Kit 版本 7.1.0(支持 Windows 7、Windows Vista、Windows XP、Windows Server 2008 R2、Windows Server 2008、Windows Server 2003)
TL;博士
与这个答案相反,使用微软自己的和未更改的工具链是完全可以的,例如独立的 WDK,它支持msvcrt.dll
“本机”链接到 (XP..7 SP1)。它甚至记录在这些工具链附带的文档中(除非您决定不安装它或闭上眼睛:))。
您“仅”必须确保在构建时针对正确的 Windows 版本(本质上与定义正确的WINVER
. 但是对于其他系统 DLL(例如kernel32.dll
,user32.dll
...)也可以这样说。
但是,使用自 2002 年以来的任何Visual C++ 进行链接msvcrt.dll
必然会产生麻烦。不要混搭。只需使用匹配那些特定 Visual C++ 版本的 CRT。