CLR via C# 读书笔记1-3

23 篇文章 0 订阅

载入 Common Language Runtime

CLR 负责托管代码的执行,所以在运行的机器上必须安装有.NET Framework。可以通过在 %SystemRoot%\System32 目录中是否存在 MSCorEE.dll 文件来判断.NET Framework 是否已经安装。特殊情况同一台机器上可能安装了多个版本的.NET Framework,你可以瞧一下这两个目录:
%SystemRoot%\Microsoft.NET\Framework
%SystemRoot%\Microsoft.NET\Framework64
.NET Framework SDK 有一个命令行工具 CLRVer.exe,它可以检索出某台机器上所有 CLR 版本,他提供的信息可以详细到每个进程使用到哪个版本的 CLR,而你只需要在命令行上使用 –all 命令开关或提供进程ID。
一个类型安全的程序集能够运行在 32-bit 或 64-bit 的 Windows 上,不需要任何代码修正。另外 Windows Store 程序或类库可以运行在 Windows RT(使用 ARM CPU) 设备上。即只要安装了正确版本的.NET Framework 设备,托管程序集都能正确运行。
在极少数的情况,开发者需要限制运行的 Windows 版本(比如要使用非托管代码获取CPU构架信息),所以 C# 编译器提供了一个 /platform 命令行开关,它允许指定生成的程序集以怎样的方式(32-bit或64-bit)运行在不同的Windows 系统上。如果你不指定,那么默认是任何cpu (anycpu),这会生成能够在所有版本Windows上运行的程序集。
使用 Visual Studio 的话可以在工程属性页的生成(Build) 选择卡中进行相关设定 (如图 1-3)。

如果你的应用程序不需要很大的内存,可以使用anycpu32bitpreferred生成32-bit的程序集,因为在 Visual Studio 中 不支持64位应用程序的edit-and-continue特性。另外32-bit应用程序能够与32-bit 的 DLL 或 COM 组件更好的互相调用。

根据 platform 开关 C# 编译器生成 PE32 或 PE32+ 头信息,并且把运行需要的 CPU 构架信息写入头信息。Microsoft 提供了2个 SDK 命令 DumpBin.exe 和 CorFlags.exe,你可以用它们来查看托管组件的头信息。

Windows 运行一个可执行文件的时候会先检查该应用程序是否需要 32-bit 或 64-bit 的地址空间, PE32 头信息可以运行在 32-bit 或 64-bit 地址空间上;PE32+ 头信息则需要 64-bit 的地址空间。同时 Windows 也检查头信息中包含的cpu构架信息,以此保证运行的机器满足运行条件。目前 64-bit 版本的 Windows 使用一种称之为WoW64 (全称 Windows on Windows 64)的技术来支持运行32-bit 应用程序。表 1-2 列出了所有这些情况:

表 1-2: /platform 对程序运行的影响

/platform 开关生成的托管模块x86 Windowsx64 WindowsARM Windows RT
anycpu
(默认值)
PE32/agnostic作为 32-bit 程序运行作为 64-bit 程序运行作为 32-bit 程序运行
anycpu32bitpreferredPE32/agnostic作为 32-bit 程序运行作为 32-bit 程序运行作为 32-bit 程序运行
x86PE32/x86作为 32-bit 程序运行作为 WoW64 程序运行无法运行
x64PE32+/x64无法运行作为 64-bit 程序运行无法运行
ARMPE32/ARM无法运行无法运行作为 32-bit 程序运行

 

在 Windows 检查完 EXE 文件的头信息后,会载入 x86, x64, 或 ARM 版的 MSCorEE.dll,然后进程的主线程会调用 MSCorEE.dll 中的一个方法,该方法初始化 CLR,载入EXE 程序集,并执行 Main 函数,此时运用程序才真正意义上开始运行。

Assemblies使用 1.0 或 1.1 版的 C# 编译器生成的程序集包含 PE32 头信息及 “未知的CPU” 构架信息。运行时 CLR 总是将它们看作 x86,在 64-bit 系统上运行时将载入WoW64运行。

当一个非托管程序调用 Win32 LoadLibrary 函数来载入一个托管程序集时,Windows 自动载入并初始化 CLR  以运行这个托管程序集的代码。在这种场景下,因为进程已经启动,这将限制程序集的可用性:64位进程无法载入使用/platform:x86开关编译的托管代码.(而本来使用/platform:x86开关编译的托管代码能够在64位Windows上载入WoW64,并正常运行)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值