1.3 载入公共语言运行时

你所构建的每个程序集可以是一个可执行程序, 或者一个包含一组类型的DLL, 这个DLL被其他可执行程序使用. 当然, CLR负责管理这些程序集中的代码的执行, 这意味着.NET Framework必须安装在宿主机器上. 微软已经创建了软件包, 你可以免费地将.NET Framework安装在客户的机器上, 一些版本的Windows在发布时就已经安装了.NET Framework.

你可以通过在%SystemRoot%/system32目录中查找MSCorEE.dll文件来判断是否安装了.NET Framework, 然而, 一台机器可以同时安装几个版本的.NET Framework. 如果你想确定你所安装的.NET Framework的版本, 在下面的注册表关键字下检查以”v”字母开头的子关键字.

HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/.NETFramework/policy

.NET Framework2.0版本开始, 微软也发布命令行方式的工具clrver.exe来给出安装在一台机上的所有版本的CLR. 这个工具也能显示出当前正在运行的进程所使用的CLR的版本, 通过-all开关或者传递进程ID来显示你所感兴趣的进程.

在开始讲述CLR如何载入程序之前, 我们需要讨论一下32-bit64-bit版本的Windows操作系统. 如果你的程序集文件只包含类型安全的托管代码, 你的代码将可以运行在32-bit64-bit版本的Windows, 而不需要修改代码. 实际上, 通过编译器产生的EXE/DLL文件可以运行在32-bitWindows, 也可以运行在x64IA64版本的64-bit Windows! 换句话说, 一个文件可以运行在任何机器上, 只要这台机器安装了.NET Framework.

在极端少见的情况下, 开发者打算将写的代码只运行在特定版本的Windows, 开发者使用了非安全的代码或者集成了非托管的代码, 而这些代码是为特定CPU工作的. 为了帮助这样的开发者, C#编译器提供了一个/platform命令行开关, 这个开关允许你指定生成的程序集是否只能运行在x86机器上的32-bit版本的Windows, x64机器上的64-bit版本的Windows, 或者Intel Itanium机器上的64-bit Windows. 如果你不打算制定平台, 默认的情况是任何的CPU都可以运行, 这也表明生成的程序集可以运行在任何版本的Windows. Visual Studio的用户可以通过项目的属性页设置一个项目的目标平台, 点击Build分页面, 然后选择目标平台列表的一个选项. 

1-3 通过Visual Studio设置目标平台

>>注意: Visual Studio没有在列表中显示出Itanium目标平台, 除非你运行VSTS版本的Visual Studio, 因为我运行的是Visual Studio Professional Edition, Itanium没有出现在列表中.


依赖于平台开关, C#编译器产生的程序集或者包含PE32或者PE32+header, 编译器也将产生所需要的CPU architecture (或者未知的)放在header. 微软发布了两个命令行工具, DumpBin.exeCorFlag.exe, 你可以使用它来检查编译器产生的header的信息.

当运行一个可执行文件时, Windows检查这个EXE文件头来决定应用程序是否需要32-bit或者64-bit的地址空间. 一个带有PE32 header的文件可以运行在32-bit或者64-bit的地址空间中, 一个带有PE32+ header的文件需要64-bit的地址空间. Windows还检查嵌入在header中的CPUarchitecture信息来确保文件是否和计算机的CPU类型匹配. 最近, 64-bit版本的Windows提供了一个技术, 允许32-bitWindows应用程序运行在其上面. 这个技术被称为WoW64 (for Windows on Windows64). 这个技术甚至允许带有x86 native代码的32-bit的应用程序运行在Itanium机器上, 因为WoW64技术能模拟x86指令集, 当然这需要重大性能的代价.

1-2显示了两件事情. 第一, 当你指定不同的/platform命令行开关开指定C#编译器时, 你得到的托管模块的类型. 第二, 应用程序如何运行在各种版本的Windows. 

1-2 /platform对生成的模块和Runtime的影响

/platform

开关

生成的

托管模块

X86 Windows

X64 Windows

IA64 Windows

anycpu

(默认)

PE32/agnostic

32位应用程序运行

64位应用程序运行

64位应用程序运行

x86

PE32/x86

32位应用程序运行

WoW64位应用程序运行

WoW64位应用程序运行

x64

PE32+/x64

不能运行

64位应用程序运行

不能运行

Itanium

PE32+/Itanium

不能运行

不能运行

64位应用程序运行

Windows检查EXE文件头之后, 决定创建一个32位进程, 或者64位进程, 或者WoW64位进程, Windows载入x86, X64或者IA64版本的MSCorEE.dll到进程的地址空间中. x86版本的Windows, x86版本的MSCorEE.dll可以在C:/Windows/System32目录下找到. x64或者IA64版本的Windows, x86版本的MSCorEE.dll可以在C:/Windows/SysWoW64目录下找到,, 64位版本(x64或者IA64)MSCorEE.dll可以在C:/Windows/System32目录下找到(这是为了向后兼容的原因). 然后进城的主线程调用定义在MSCorEE.dll中的一个方法. 这个方法初始化CLR, 载入EXE程序集, 然后调用入口点方法(Main). 在这个入口点, 托管的应用程序开始运行.

>>注意: 通过7.0或者7.1版本的C#编译器构建的程序集包含一个PE32 header, CPU-architectureagnostic. 然而, 在载入时, CLR认为这些程序集只是x86版本的. 对于可执行文件, 这增加了应用程序运行在64位操作系统的可能性, 因为可执行文件将在WoW64中载入. 

如果非托管的应用程序调用LoadLibrary来载入一个托管的程序集, Windows知道要载入并初始化CLR (如果还没载入CLR) 来处理程序集中的代码. 当然, 在这种场合, 进程已经正在运行了, 这将限制程序集的可用性. 例如, 一个托管的程序集是以/platform:x86开关编译的, 那么它将不能被载入到一个64位的进程中, 然而一个用这种开关编译的可执行文件可以被载入到运行着64位版本WindowsWoW64.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值