17

如果没有安装 JRE,当我们运行 java 程序时,它不起作用。
我发现大多数著名的应用程序(例如 Google chrome 浏览器)都是用 C++ 编写的。那么,Windows 是如何在没有任何 C++ 运行时环境的情况下运行这样的程序的呢?安装时到底发生了什么?

4

4 回答 4

25

那么windows如何在没有任何C++运行时环境的情况下运行这样的程序呢?

问题的前提实际上是不正确的。至少在 Windows 上,实际上存在 C++ 的运行时环境。此运行时的一个组件(可能是最重要的一个)称为 C 运行时或 CRT。:-)

通常在您的程序甚至进入main()函数之前,CRT 会执行一堆初始化例程,当您从main()函数返回时,它会自行清理。这种舞蹈的全部意义在于提供几乎所有 C 和 C++ 程序都需要的标准功能。

如果您在启动 Windows 程序时遇到过包含缺失msvcrt.dll或类似情况的错误(例如msvcr110.dll,对于较新的程序),那么程序所抱怨的就是缺少 CRT。msvcrt.dll是实现 CRT 的文件。它代表“Microsoft Visual C 运行时”。

显然,msvcrt.dll它的亲戚随 Windows 操作系统一起提供,这就是为什么您通常不会遇到与 JRE 不同的缺少运行时环境的问题,JRE 必须由用户或计算机制造商安装。

但是,Windows C++ 应用程序被编译为使用特定版本的 MSVCRT,如果您的MSVCRT 版本错误,那么操作系统会以与丢失相同的方式抱怨。* 安装程序通常做的是检查操作系统具有正确的版本,如果没有,它会从自己的安装文件将其复制到您计算机上的某个位置。

然而,MSVCRT 并不是所有 Windows 程序都能正常工作的必要或充分条件。完全有可能编写一个不依赖于 MSVCRT 的程序,也完全有可能一个 Windows 程序将具有 MSVCRT 以外的依赖项。几乎所有重要的 Windows 程序都将依赖于 MSVCRT 和其他操作系统组件。程序的安装程序也会检查这些。

JRE 和 MSVCRT 之间有一些重要的区别。一个很大的区别是JRE为Java应用程序实现了一个虚拟机环境(这就是它实现“跨平台”能力的方式),这可能涉及即时编译等,而MSVCRT只提供标准功能,什么都不做关于 C++ 程序的汇编代码。


*这并不完全正确,因为 C++ 应用程序可以静态链接到不依赖于 DLL 的 MSVCRT。但是,大多数 Windows C++ 应用程序动态链接到它,在这种情况下需要正确的 DLL。

于 2012-09-04T06:01:28.137 回答
3

这个问题似乎很明显,但如果我们深入挖掘,它似乎远非显而易见。让我给你一个更抽象的观点:

每种语言都可以由合适的机器“执行”,该机器将语言指令连接到“执行”操作的特定硬件。不同之处在于“连接”是如何完成的:它有多直接以及何时设置向上。

Windows(但同样适用于 linux)机器至少是一组由某些“重要”DLL(例如 Kernel.dll)公开的函数,这些函数将被处理器机器代码调用。

C 程序通常在编译时被翻译成机器代码,以放置尊重该“协议”的系统调用。不需要任何其他功能的程序可以在该环境中本地执行。

需要其他功能的程序可以:

  • 静态链接到将函数实现为机器代码的库(实际上合并了它们的代码):这使得程序仍然可以本地执行。
  • 动态链接到这些库:程序需要在启动或执行期间加载和链接这些库:如果这些库本身已经是操作系统的一部分,则程序刚刚运行,否则,这些库必须以某种方式放置在某处程序可以找到它们(这是 C 运行时支持的情况,对于用于编译操作系统本身的版本以外的版本)

顺便说一下,Java 语言的设计和实现方式,Java 程序并不直接翻译成机器代码。它翻译成一种中间语言(字节码),必须用作interpeter(java机器)的“输入”,通过在底层机器上执行机器代码来实际执行其指令。

由于 Windows 本身不是用 Java 编写的,因此它本身不需要这样的解释器,因此您无法直接在 Windows 安装中找到它,但如果需要,您必须将它放在那里。

于 2012-09-04T06:59:58.650 回答
2

to clarify that, a java program is compiled to bytecode via jdk and then runs in the jre

a c++ programm is directly compiled to machine readable code, just like the jre has to be compiled to run in windows

于 2012-09-04T06:05:03.493 回答
2

运行时(或 C 或 C++ 标准库)通常随操作系统(glibc、msvcrt...)一起安装。

C/C++ 程序也可以“静态”编译,其中程序使用的库部分被链接(合并)到可执行文件中,因此程序在它自己的二进制文件中有库。

至于执行Java代码的“虚拟机”。C++ 通常被编译成将要运行的系统的本机机器代码。CPU是将运行它的非虚拟机。

也可以将 C++ 程序编译成各种“字节码”(.NET CLR、LLVM),但这并不常见。

于 2012-09-04T06:24:03.757 回答