【发布时间】:2019-12-14 21:20:01
【问题描述】:
假设我在 Windows 上启动了一个 .exe 文件。该文件可以用 C++、Java 或 C# 编写并编译为 .exe。
对于 C++,操作系统可以直接执行命令。但是 Windows 怎么知道它必须为 Java 或 C# 启动运行时(JVM 或 CLR)?另外如何决定启动哪个Runtime?
【问题讨论】:
标签: java c# c++ windows operating-system
假设我在 Windows 上启动了一个 .exe 文件。该文件可以用 C++、Java 或 C# 编写并编译为 .exe。
对于 C++,操作系统可以直接执行命令。但是 Windows 怎么知道它必须为 Java 或 C# 启动运行时(JVM 或 CLR)?另外如何决定启动哪个Runtime?
【问题讨论】:
标签: java c# c++ windows operating-system
对于 CLR,您正在查看的信息是可执行文件的 PE 标头。 Wiki 和微软Spec。 CLR 的部分列表中有一个部分。
在 .NET 可执行文件中,PE 代码部分包含一个存根,该存根调用 CLR 虚拟机启动项,_CorExeMain 或 _CorDllMain 中 mscoree.dll,就像它在 Visual Basic 可执行文件中一样。虚拟的 然后机器使用 .NET 元数据存在,其根, IMAGE_COR20_HEADER(也称为“CLR 标头”)由 PE 标头数据中的 IMAGE_DIRECTORY_ENTRY_COMHEADER[6] 条目 目录。 IMAGE_COR20_HEADER 非常类似于 PE 的可选标头, 本质上是为 CLR 加载程序发挥作用。2
与 CLR 相关的数据,包括根结构本身,是 通常包含在通用代码部分 .text 中。它是组成 几个目录:元数据、嵌入式资源、强名称和 很少有本机代码互操作性。元数据目录是一组 列出程序集中所有不同 .NET 实体的表, 包括类型、方法、字段、常量、事件以及 它们之间以及对其他程序集的引用。
来自微软:
.cormeta 部分(仅限对象)CLR 元数据存储在此 部分。用于表示目标文件包含托管 代码。元数据的格式没有记录,但可以交给 到用于处理元数据的 CLR 接口。
对于 Java,有一个加载器将嵌入的 JAR 加载到可执行文件中(很像过去的 DOS 加载器或 EXE 打包器)。后一种技术几乎可以应用于任何东西,例如作为资源嵌入在 .EXE 中的 .bat 文件,由某个加载器加载和执行。这不需要 Windows 加载程序的任何帮助。
【讨论】:
一般情况下,windows 只识别 PE 格式,当 pe 可执行文件启动时,它的职责就是引导全域。
为了演示它,在 unix/linux 世界中有crt0,它是开源的,你可以查看 crt0 是如何工作的。
顺便说一句,除了crt0,还有crt1、crti、crtn,分别运行在bootstrap或termination的不同阶段。
【讨论】: