Rex's Blog

Funny is learning everything!

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

前言:

---.Net 平台创新就是关于人、信息和设备之间的互联。其框架则是一个抽象了XML WEB服务的开发平台。

---客户机通过创建特殊格式的XML来描述一个服务器请求,然后通过企业内部网或者互联网来发送它(典型地利用HTTP协议)。服务器知道怎样分析这些XML数据,处理客户的请求,然后再以XML作为响应回传给客户机。其中SOAP(简单对象访问协议)在这里用来描述通过HTTP协议发送的特殊格式的XML。

---提供Web服务的计算机必须运行在一个能够侦听SOAP请求的操作系统上。

---.NET框架包含两个部分:通用语言运行时(CLR)和.NET 框架类库(FCL)。.NET 框架本身又是.NET平台创新中一个关键的组成部分。

---CLR和FCL提供的一部分重要服务:
A、一致的编程模型:在.NET框架下,所有的应用程序服务都将一种一致的、面向对象的编程模型提供给开发人员;
B、简化的编程方式:CLR完全抛弃了诸如:注册表、全局唯一标识符(GUID)、IUnknow、AddRef、Release、HRESULT等概念。它的目的就是为了简化Win32和COM环境下所需要的各种繁杂的基础构造。
C、可靠的颁布机制:.NET框架采用了一种新型的颁布机制来隔离应用程序组件,这种隔离策略可以保证一个应用程序总能加载他当初生产和测试时所使用的组件。
D、轻便的部署管理:在.NET框架下,组件将不再受注册表的任何引用。
E、广泛的平台支持:因为其采用了通用中间语言(CIL),是其与平台关联大大减少。
F、无缝的语言集成:因为使用通用语言规范(CLS)标准,各语言之间可以进行无缝集成。
G、简便的代码重用:
H、自动化的内存管理(垃圾收集):CLR会为我们自动追踪资源的使用情况,从而确保应用程序不致泄露资源。
I、坚实的类型安全:类型安全确保了系统所分配的对象总能够以正确的方式被访问。
J、丰富的调试支持:CLR完全支持跨语言调试。
K、统一的错误报告:CLR中,所有失败的调用都是通过异常来报告的。另外,CLR还提供了内置的堆栈遍历机制,这使得我们可以很容易的定位任何的bug和调用失败。
L、全新的安全策略:CLR中的代码访问安全(CAS)为我们提供了这种方式的实现机制。
M、强大的互操作能力:为了方便现存代码和组件的重用,.NET框架从一开始就对访问现有COM组件,以及调用传统DLL中的WIN32函数提供了完全的支持。

第一部分:Microsoft .NET 框架基本原理

第一章、Microsoft .NET框架开发平台体系架构


目标:对.NET框架的体系架构有一个总体的认识,并对.NET框架中出现的一些新的技术和术语有一个基本的了解。

---.NET框架的核心便是通用语言运行时(CLR)。我们可以用任何支持CLR的编程语言来创建源代码文件。然后用相应的编译器来做语法检查和源代码分析。但是不管使用的是何种编译器,最后生成的结果都是一个托管模块(Managed Module)。而托管模块式一个需要CLR才能执行的标准Windows可移植可执行(Portable Executable,简称PE)文件。

---托管模块的组成部分:

部分    

描述

  
PE表头 

该表头指出了文件的类型:GUI(图形用户界面),CUI(控制台用户界面),或者DLL(.NET中的DLL特指程序集文件的一种形式)。另外,该表头还包括了一个时间标记用户表示文件创建的时间。对于仅包含IL代码的模块,该表头的大多数信息会被忽略。对于包含有本地CPU代码的模块,该表头还会包含有关本地CPU代码的一些信息。

CLR表头 包含标识托管模块的一些信息(可以被CLR或者一些实用工具解析)。这些信息包括托管模块所需要的CLR版本号,一些标记,托管模块入口点方法(Main方法)的MethodDef元数据标记,以及有关托管模块的元数据、资源、强明目、标记和其他一些意义不是太大的新型的位置和尺寸。
元数据 每个托管模块都包含有一些元数据表。元数据表主要分两种,一种用于描述源代码中定义的类型和成员,一种用于描述源代码中引用的类型和成员。
中间语言(IL)代码 编译器在编译源代码时产生的指令。CLR在运行时会将IL代码编译成本地CPU指令。


---CLR实际上并不和托管模块打交道,它直接打交道的对象是程序集(Assembly)。

---程序集是一个抽象的概念,它是一个或多个托管模块,以及一些资源文件的逻辑组合。其次,程序集是组件复用,以及实施安全策略和版本策略的最小单位。根据我们对编译器和相关工具所做的选择,程序集可以是一个文件或者多个文件。

---程序集中的模块还包含他所引用的程序集的一些信息(如版本号信息)。这些信息使得一个程序集得以实现自描述(Self-Describing)。换句话说,CLR知道执行一个程序集所需要的所有内容,它不需要再在注册表或者活动目录(Active Directory)中获取额外的信息。

---通过判断%windir%\system32目录是否存在MsCorEE.dll(微软组件对象运行时执行引擎)文件来判断一个机器中是否安装了.NET框架,通过查看注册表如下位置信息,可以判断是何种.NET版本。HKEY_LOCAL_MACHINE\SOFTWARE\MICROSOFT\.NETFRAMWORK\POLICY.

---托管EXE加载并初始化CLR的过程:
A、当编译器/链接器创建一个可执行程序集时,下面这个6字节的X86 Stub函数将被嵌入到PE文件的.text部分:JMP _COREXEMAIN。
B、由于_CorExeMain函数是从MSCorEE.dll动态链接库中导入的,所以MSCorEE.dll将在程序集文件的导入(.idata)部分被引用。
C、当托管EXE文件被调用时,Windows将像对待通常(非托管)的EXE文件一样来对待它。Windows加载器首先加载该文件,然后检查其.idata部分发行MSCorEE.dll需要被加载到进程的地址空间,于是加载器获取MSCorEE.dll中_CorExeMain函数的地址,同时修正托管EXE文件中Stub函数的JMP指令。
D、之后,进程的主线程开始执行修正后的X86 Stub函数,该函数立即跳转到MSCorEE.dll中的_CorExeMain函数上。
E、_CorExeMain函数接着初始化CLR,并查看可执行程序集的CLR表头以确定要执行的托管入口点方法。入口点方法找到后,其IL代码随之被编译成为本地CPU指令。
F、CLR跳转到编译后的本地指令上(使用进程的主线程)。至此,托管应用程序才算开始真正运行。

---托管DLL的情形与此类似过程。只是函数使用:_CorDllMain.

---在WINDOWS XP和WINDOWS .NET服务器家族上,当一个托管程序集被调用时(通常通过CreateProcess或者LoadLibrary),操作系统的加载器会通过查看PE文件表头的第14条目录项来检测该文件中是否包含托管代码。如果该目录项存在且不为0,那么加载器将忽略该文件的导入部分(.idata),而自动将MSCorEE.dll加载到进程的地址空间中。一旦加载完成后,操作系统的加载器将使该进程的线程直接跳转到MSCorEE.dll中相应的函数上。6字节的X86 Stub函数在运行Windows XP和Windows.NET服务器家族的操作系统上将完全被忽略。

---最后,托管PE文件总是使用32位(而非64位)的PE文件格式。在64位的Windows系统上,操作系统加载器检测到32位的托管PE文件后会自动创建64位的地址空间。

posted on 2006-09-04 14:42  Rex.Sun  阅读(271)  评论(0编辑  收藏  举报