不使用CRT编译C++

10

基本上标题已经说得很清楚了:我想在编写C++代码时完全禁用CRT。

我希望能够在Win98上以及所有其他系统上运行exe文件。 只使用纯本地的C++编程。

我正在使用的编译器是Visual Studio。然而,如果需要的话,我愿意更改编译器。


3
你为什么想要在Windows 98上禁用CRT? - Sean
2
当然可以,但我想知道你为什么要这样做。 - Sean
8
答案几乎肯定是“你不能”。但是回到最初的阶段,向我们解释一下:(a) 你的程序大致上是做什么的, (b) 你遇到的具体问题, (c) 为什么你认为禁用 CRT 可以解决这些问题,以及 (d) 为什么你认为需要支持已经过了厂商维护期限的操作系统。 - zwol
2
没有输入和输出的程序可能会缺乏吸引力。 - user1196549
5
回复所有“XY问题” / “你做不到”的评论者,对于关于“没有CRT的C ++”所提出的问题(我不确定是否兼容Win98),这里有一篇CodeProject文章,其中阐述了一些人可能希望这样做的原因,并展示了一些源代码。有时候像这样的主题本身就很有趣,即使大多数程序都不会使用自定义运行时库。 - jrh
显示剩余13条评论
6个回答

13
你可以删除所有Microsoft提供的CRT的引用,并将其替换为自己的轻量级CRT。具体操作步骤有点冗长,但伴随着代码示例在这里得到了很好的概括: https://www.codeproject.com/articles/15156/tiny-c-runtime-library 这些指南有点过时,但是我成功地在Visual Studio 2017和Windows 10上运行了部分tlibc的内容。除了FILE API之外,似乎所有东西都可以编译和运行。遵循以下步骤:
1. 创建控制台应用程序项目。 2. 禁用所有标准库的链接(/NODEFAULTLIB)。 3. 禁用所有编译器运行时检查(RTC)。
在该点上,tilbc源码已经编译并运行(不包括过时的FILE部分)。
然而,OP的实际问题与此完全不同。CRT不能归咎于错误“exe不是有效的Win32应用程序”。此错误发生在实际执行二进制代码之前很久,包括在main()/winmain()之前执行的CRT。通常情况下,在尝试在x86操作系统上运行x64二进制文件时会出现此错误。理论上,即使使用正确的SDK版本标志来包括,Visual Studio 2017工具链也可以构建适用于Windows 2000和Win98的应用程序。
即使在使用错误的SDK或编译器标志的情况下,报告的错误也将是其他内容--最有可能是DLL加载失败或弹出一个类似于“该程序无法启动”的弹出窗口后跟随着兼容性模式选项。


2
您可以使用正确的项目设置静态链接C++运行时,但即使如此,最多也只能在Windows XP上工作。
您可以在这里找到静态链接标准库的方法,但以防链接失效:

在Visual Studio开发环境中设置编译器选项

1)打开项目的属性页对话框。有关详细信息,请参见如何:打开项目属性页。

2)展开C/C++文件夹。

3)选择代码生成属性页。

4)修改运行库属性。

如果您真的想在Windows 98上使其正常工作,则需要使用较旧版本的Visual Studio并执行类似上述步骤的操作。

1
VC++非常使用CRT来编写本地C++代码,相关的库称为msvcrt<toolchain-version>.dll。请注意中间的三个字母crt - n. m.
@Prionum,看我的回答,基本上你需要一个支持你所针对的Windows版本的编译器,并且你需要至少进行一些不同的构建。我甚至不确定最近的Visual Studio是否仍然支持Win 98。你应该提出一个新问题,询问哪些编译器支持Win98(或你想要的系统)以及如何设置正确的项目设置。 - CoffeDeveloper
2
据我最近了解,Visual Studio的更新版本如果你要求的话,会包含对XP的特殊支持,但不早于此版本。 - OMGtechy
是的,Win 2k或更早版本已经太老了(XP已经太老了,而且顺便说一句,Vista在任何地方都支持不好)。 - CoffeDeveloper
我仍然非常同情那些觉得他们仍然需要支持XP的软件供应商和那些觉得他们仍然无法承担升级到比XP更新的系统的终端用户。但Win98和Win2K已经过时了。 - zwol
显示剩余2条评论

2

虽然有可能做到,但是有很多缺点,因此我不建议这样做(我不会详细解释这些缺点)。

你为什么要针对Win98?现在几乎没有人使用它。我建议使用Windows Vista或更高版本,但完全取决于你。

首先,你需要禁用优化,将RT lib设置为MT,禁用安全检查(这会使你的应用程序不太安全!),以及其他一些事项。要做到这一点,请转到C/C++设置并将/Od /MT /GS-添加到命令行中。

接下来进入代码生成,将启用C++异常设置为“否”。 然后进入链接器,并将/NODEFAULTLIB添加到命令行中。 最后,导航到高级选项并设置入口点。

完成上述步骤后,你就可以开始了!


1

在不知道需要做什么的情况下,帮助起来很困难。通常情况下,您不能删除CRT,原因在这里:

  • 入口点(从控制台获取输入)
  • 提供C和C ++中使用的公共函数

这意味着如果没有CRT,则无法使用stdio(除非稍后手动链接它),并且您也无法在控制台中运行应用程序

您可以通过创建静态库来删除CRT,这尽可能接近纯本地C ++,如果您不在其中链接外部库(那么,对象文件比静态库更接近本地C ++)。

根据操作系统,您甚至可能无法在没有CRT的情况下调用二进制文件中的函数(例如Windows)。因此,如果您只是想避免二进制开销,最好的选择是具有静态/动态库,该库链接到其他“启动器”或仅动态调用(仍然需要一种检索入口点的方法)。

再次强调,如果您没有提供足够的细节,很难确定您需要什么。

编辑:

如果您需要在较旧的win98上运行,则使用支持win98的编译器,并使用编译器标志指定要编译为win98。

我们已经从评论中了解到了真正的 OP 问题。 - SergeyA
这些评论是在回答时添加的(如果问题中添加了新评论,SE不会重新加载)。 - CoffeDeveloper
是的,但一旦你知道了它,你实际上可以编辑答案来回答实际问题。 - SergeyA

1

您可以尝试使用不同的编译器,例如Symantec C++ 7.5或Digital Mars C++。

我有使用Symantec编译器制作的程序,即使在Win 11上也能完美运行。

实际上,向90年代应用程序pfe32(程序员文件编辑器)的作者致敬,它可以在任何Windows版本上运行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接