您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 信息化管理 > Windows Mobile 进阶系列
WindowsMobile进阶系列CopyrightReservedbyFreescHuang第一回.真的了解.NETCompactFramework吗?作为系列文章的开篇,有必要先详细了解一下基于CE.NET的.NETCompactFramework(以后简称.NETCF),本文叙述了.NETCF的设计目标,架构特征和执行环境。.NETCF的目标在哪里?1.专为设备设计的便携式小型.NETCLR具有.NETFramework的子集属性,支持多种语言开发。我们知道,在英文里面“便携式”对应的单词是Portable,这个Portable我们可以从两方面理解:一方面,.NETCF工作在一个灵活的,移动的,资源有限的环境下;另一层意思则体现在.NETCF本身的特性上,比如说它与OS的宽松耦合,OS管与CLR托管的不同就在这里。从编程的角度Portable体现在很多“和谐”的方面,比如I/O内存映射,比如仅支持Unicode编码等等。2.与VisualStudio系列IDE高度兼容不仅仅是编译,调试托管和非托管的代码,在VisualStudio2008中你还可以通过DeviceSecurityManager来为已连接的设备管理证书和设置安全级别。甚至可以编程访问模拟器资源。3.与主机的操作系统有良好的共存性这个共存性是多方面的,包括应用程序的执行模型,内存管理,用户输入和UI接口。这些在后面的文章中您都会接触到。当然还有一些要求是.NETCF做不到的,暂时也不是它的目标,为了不使大家对.NETCF的要求太“苛刻”,我觉得必须把这些“非目标”也列举出来:1.CompactVS.Full.NETCF不是对桌面版本.NETFramework的部分简单平移,把.NETFramework完整移植到移动设备上并不是.NETCF的目标,尽管表面上看起来有些内容和完整版的.NETFramework是一致的,但是其实现方式可能很不一样。2.实时性WindowsMobile是一个32位的民用操作系统,你不能要求它和VxWorks一样工作!.NETCF也并没有提供对强实时性的支持(问题是您真的需要那么高的实时性吗?)。3.语言支持.NETCF目前支持的开发语言并不像完整版本的那么丰富,目前比较流行的是C/C++,C#和VB。但是.NETCF完全支持精简版本的ECMACLIProfile,这意味着你也可以为更多的语言编写针对.NETCF的编译器。WindowsMobile进阶系列CopyrightReservedbyFreescHuang.NETCF的结构模型.NETCF的架构跟完整版的.NETFx有相似之处,同时又具有自己特色,如图表1所示。图表2.NETCFArchitectureApplication.NETCFCLRWinCEOperatingSystemDeviceHardwareManagedCodeApplicationNativeCodeApplicationSoundVideoNetworkTouchScreenMemoryCPUAPIExposure,ProgramLoader,MemoryManagement,WindowingDeviceSpecificClassLibrariesBaseClassLibrariesExecutionEnginePlatformAdaptorLayerMSCoree.dllManagedCode(MSILbytecodes)JITCompilerJITCompiledCode(VeryNativeCode)WindowsMobile进阶系列CopyrightReservedbyFreescHuang最下面的是硬件层,由于图幅有限,我仅列出了主要的一些硬件,而这所有的硬件都是由WindowsCE操作系统所控制的,WinCE提供了内存管理规范和用于加载可执行文件的ProgramLoader,ProgramLoader负责将可执行文件Push到内存中并启动它。当然,WinCE作为操作系统还有很多其他职能,比如线程管理,绘制窗体,相应来自GUI的事件,管理网络连接等等。作为使用.NETCF的程序员,我们主要关注的是图中虚线以上的部分,现在来看看.NETCF的CommonLanguageRuntime(CLR),图中灰色背景的方框表示.NETCFCLR。用NativeCode(如C/C++)编写的基于WinCE的程序,直接被编译成CPU可以识别的指令,但是依赖WinCE去加载它们并提供所需的服务。而CLR是一个用来托管应用程序的平台,托管的应用程序被编译成MicrosoftIntermediateLanguage(MSIL),IL在这里提供了一个与CPU松耦合的机会,CLR根据不同的CPU体系结构将IL编译成不同的CPU指令,这一点在行为上与桌面版的CLR是一致的。有一点要弄清的是托管的EXEs或者DLLs是由IL构成的,并不能被CPU直接执行,而是需要被CLR编译成适用于本地CPU的指令或者是本地代码。可见,CLR的工作是执行托管代码,这个过程就是托管代码本地化并被执行的过程,简单来讲,它包括以下步骤:1.将IL从文件系统加载到内存中。2.这些IL中的部分或全部将被转化成本地代码供CPU执行3.如果这些IL引用了某些DLL的内容,则当DLL被找到并正确加载后,这些被用到的部分也会被转化成本地代码并被执行。可见这个JustInTimeCompiler在CLR的运行中扮演着十分重要的角色。在.NETCompactFramework中有两种形式的JIT编译器,iJIT和sJIT:iJIT适用于所有的CPU,如ARM,MIPS,SHx和X86等。iJIT较简单,编译的速度也比较快,但是它编译出来的本地代码并不像sJIT那样经过优化的。sJIT编译器是ARM指令体系下特有的,它充分利用了AMR处理器的优势。虽然编译速度不及iJIT,但是编译后的代码在第二次运行的时候会迅速得多。所以在编写应用程序的时候你应当考虑到你的程序是否是专为基于ARM的设备而设计,或是有考虑到用户的机器可能是一台性能一般的MIPS。默认状况下,仅当无法使用sJITCompiler的时候,CLR才会选择使用iJIT的方式。这样做的原因是,通常在程序执行过程中,花在JIT编译上的时间和执行程序的时间相比是微不足道的。需要注意的是在我们的程序当中应当避免额外的JIT行为,因为有些情况下,这会明显影响到应用程序的运行速度,当然,要做到这一点需要您对CLR有一定的认识。JIT按需编译,并尝试对编译后的代码在程序生命周期内进行保留,这样下一次调用的时候就不必再执行JIT了。说是尝试是不考虑内存的缘故,这样的缓存不会无限制的进行下去,当内存不够用时,CLR会逐方法的将JIT过的代码清除掉,这就是所谓的CodePitching。清除掉之后再次调用该方法CLR就会重新进行JIT编译。有趣的是这个Pitch的过程也是智能化的,哪些最不常用的方法的JITedCode会被最先清除。如果我们的程序编写不当,在某些极端情况下,重复的JIT可能会出现在一个循环中,每一次循环都将重新JIT一次,这显然会使性能大打折扣,而且很可能使你的程序因此down掉。WindowsMobile进阶系列CopyrightReservedbyFreescHuang性能问题在今后的文章中还会专门介绍。用一句话概括图表1,可以说“是.NETCFCLR使得.NET应用程序得以运行在各种不同的基于WindowsCE.NET的移动设备上”。CompactCLRVS.FullCLR对于习惯了桌面应用的程序员,有必要了解一下精简版的.NETCF与完成版本的.NETCF有哪些不同。首先从体系结构上,.NETCFCLR与桌面版本的CLR不尽相同。从图表一我们看到,.NETCFCLR构建在PlatformAbstractionLayer(PAL)之上,PAL位于执行引擎与OS之间,将CLR从硬件的层面抽象出来,如果您需要将CLR移植到其他平台,只需要改变PAL层,并为该平台的CPU编写相应的JITCompiler。正是这种灵活性,使得.NETCFCLR也随着日新月异的Mobile硬件设备不断前行。在JIT编译之后,.NetCFCLR对生成的本地代码的处理也与桌面版本不同。在桌面版本的CLR中,JIT过后的代码有时候会在程序退出之后依然存在,这样在它下次加载的时候会快一些。但是.NetCFCLR仅仅在程序运行期间保存JIT生成的代码。每一次程序启动,JIT编译必然再次发生。在对程序集的定义上面,.NetCFCLR和桌面版本的CLR也有所不同,桌面版本的程序集支持多文件构成一个程序集。而.NETCFCLR不支持这一性质,这在移植桌面应用程序到.NETCF下的时候是需要注意的。这些不同都是与移动设备本身的特性密不可分的,如果您要了解更多.NETCF与.NETFramework的不同,请参照这里.NetCF应用程序的执行环境我们通常在调试程序的时候主要有两种执行环境---模拟器和真实设备。要注意,这里模拟器并不是说就是在Windows(x86)下面工作的用来模仿基于WinCE操作系统行为的一个程序,而是一个真正的CE.NET或者WindowsMobile操作系统的镜像,只是它是由x86的操作系统所编译并运行。而在真实设备上运行的程序则是.NETCFCLR所掌管的一个实例。前面讲JIT的时候已经提到过应用程序的执行了。我们说“是.NETCFCLR使得.NET应用程序得以运行在各种不同的基于WindowsCE.NET的移动设备上”。CLR无疑是.NET最重要的组成部分,它负责将已编译成MSIL的托管程序集装配到应用程序域中,以JIT的编译方式将他们编译成本地代码供宿主CPU执行,同时它还要在运行过程中管理内存分配,垃圾回收以及加载其他类库等。WindowsMobile进阶系列CopyrightReservedbyFreescHuang从组成上可以把.NETCFCLR分成两部分:执行引擎和基础类库。执行引擎与底层操作系统提供的各种服务接口打交道(这离不开PAL的作用),而基础类库则是构成.NET应用程序的基本程序单元。其中基础类库发展到现在已经十分丰富,想必大家也比较熟悉,在此无需也无法作多的介绍。下面看看执行引擎(ExecutionEngine)。执行引擎为托管代码的执行提供了众多基本服务,比如:程序集的Loader和全局程序集缓存(GAC)元数据引擎/缓存对类层次模型的描述“反射”技术(关于程序集的加载,后续的文章中也会介绍)JIT的编译和校对机制安全的执行体系异常探知,本地代码互操作,OS安全性保障垃圾回收器对调试的支持为Debug版本的程序生成可方便调试(如断点)的代码对某些托管的API(ClassLibs)采用本地化的实现执行引擎(EE)是.NET的核心组件,它掌管着.NETCF的所有其他东西。其本身是一个本地可执行的文件,它通过平台抽象层(PAL)与底层操作系统进行交互,他们共同被安置在一个可执行文件中(Mscoree.dll),你可以在Windows/System32目录下面找到它。PAL层(thePlatformAdaptationLayer)就如同基于WinNT的操作系统(WindowsNT4.0,2000,XP,2003)的硬件适配层(HAL),用于在常规代码和不同硬件水平的CPU之间做一个适配。正是PAL的存在,使得.NETCF的程序集能运行在使用任何CPU的任何WinCE兼容的设备上,而以往用经典的EVC开发的应用程序可能还需要为不同的OS和CPU单独编译。,另外,.NETCF同样支持GAC,你可以以可复用的方式部署你的应用程序,它是通过预加载某些基础类库,你可以在你的应用中通过应用的方式来调用他们,这样减少了代码量,也提高了性能。在异常处理方面,.NETCF还有一个有趣的特点,我们知道,通常一个error发生的时候,一条错误消息会随之而来,开发者可以捕获到这个消息,并选择怎
本文标题:Windows Mobile 进阶系列
链接地址:https://www.777doc.com/doc-1544 .html