如果没有安装 JRE,当我们运行 java 程序时,它不起作用。
我发现大多数著名的应用程序(例如 Google chrome 浏览器)都是用 C++ 编写的。那么,Windows 是如何在没有任何 C++ 运行时环境的情况下运行这样的程序的呢?安装时到底发生了什么?
4 回答
那么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。
这个问题似乎很明显,但如果我们深入挖掘,它似乎远非显而易见。让我给你一个更抽象的观点:
每种语言都可以由合适的机器“执行”,该机器将语言指令连接到“执行”操作的特定硬件。不同之处在于“连接”是如何完成的:它有多直接以及何时设置向上。
Windows(但同样适用于 linux)机器至少是一组由某些“重要”DLL(例如 Kernel.dll)公开的函数,这些函数将被处理器机器代码调用。
C 程序通常在编译时被翻译成机器代码,以放置尊重该“协议”的系统调用。不需要任何其他功能的程序可以在该环境中本地执行。
需要其他功能的程序可以:
- 静态链接到将函数实现为机器代码的库(实际上合并了它们的代码):这使得程序仍然可以本地执行。
- 动态链接到这些库:程序需要在启动或执行期间加载和链接这些库:如果这些库本身已经是操作系统的一部分,则程序刚刚运行,否则,这些库必须以某种方式放置在某处程序可以找到它们(这是 C 运行时支持的情况,对于用于编译操作系统本身的版本以外的版本)
顺便说一下,Java 语言的设计和实现方式,Java 程序并不直接翻译成机器代码。它翻译成一种中间语言(字节码),必须用作interpeter(java机器)的“输入”,通过在底层机器上执行机器代码来实际执行其指令。
由于 Windows 本身不是用 Java 编写的,因此它本身不需要这样的解释器,因此您无法直接在 Windows 安装中找到它,但如果需要,您必须将它放在那里。
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
运行时(或 C 或 C++ 标准库)通常随操作系统(glibc、msvcrt...)一起安装。
C/C++ 程序也可以“静态”编译,其中程序使用的库部分被链接(合并)到可执行文件中,因此程序在它自己的二进制文件中有库。
至于执行Java代码的“虚拟机”。C++ 通常被编译成将要运行的系统的本机机器代码。CPU是将运行它的非虚拟机。
也可以将 C++ 程序编译成各种“字节码”(.NET CLR、LLVM),但这并不常见。