仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 1274|回复: 11
打印 上一主题 下一主题

[学习教程] ASP.NET网站制作之[你必需晓得的.NET]第二十五回:熟悉元数据和IL(中)仓酷云

[复制链接]
兰色精灵 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-1-18 11:21:54 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
语言是不是不是最重要的?系列文章目次索引:《你必需晓得的.NET

<br>说在,开篇之前书接上回[第二十四回:熟悉元数据和IL(上)],我们对PE文件、程序集、托管模块,这些观点与元数据、IL的干系举行了需要的展垫,同时特地熟习了以ILDASM工具举行反编译的基础办法认知,上面是时分来懂得甚么是元数据,甚么是IL这个话题了,我们持续。

很早就有说说Metadata(元数据)和IL(两头言语)的设法了,一向在这篇入手下手才算兢兢业业的对这两个阶层兄弟投往些细关切,固然来得没有《第一回:恩仇情仇:is和as》那末敏捷,可是Metadata和IL倒是相对分量级的内容,值得我们在任什么时候间存眷,本文就是入手下手。3元数据是甚么?
元数据,就是形貌数据的数据。这一观点并不是CLR之首创,Metadata存在于任何对数据和数据干系中,比方程序集清单信息也被称为程序集元数据。而分歧体系的元数据也响应具有自己的特性,.NET元数据也是云云。那末,CLR元数据形貌的是哪些内容呢?正如前文的形貌一样,编译以后,范例信息将以元数据的情势保留在PE格局文件中。.NET是基于面向对象的,以是元数据形貌的次要方针就是面向对象的基础元素:类、范例、属性、办法、字段、参数、特征等,次要包含:


  • 界说表,形貌了源代码中界说的范例和成员信息,次要包含:TypeDef、MehodDef、FieldDef、ModuleDef、PropertyDef等。
  • 援用表,形貌了源代码中援用的范例和成员信息,援用元素能够是统一程序集的其他模块,也能够是分歧程序集的模块,次要包含:AssemblyRef、TypeRef、ModuleRef、MethodsRef等。
  • 指针表,利用指针表援用未知代码,次要包含:MethodPtr、FieldPtr、ParamPtr等。
  • 堆,以stream的情势保留的信息堆,次要包含:#String、#Blob、#US、#GUIDe等。
如前文所述,我们以ILDasm.exe能够经由过程反编译的体例,经由过程实行Ctrl+M快速键来猎取该程序集所利用的MetaData信息列表,在.NET中每一个模块包括了44个CLR元数据表,以下:
表纪录元数据表申明0(0)ModuleDef形貌以后模块1(0x1)TypeRef形貌援用Type,为每一个援用到范例保留一笔记录2(0x2)TypeDef形貌Type界说,每一个Type将在TypeDef表中保留一笔记录3(0x3)FieldPtr形貌字段指针,界说类的字段时的两头查找表4(0x4)FieldDef形貌字段界说5(0x5)MethodPtr形貌办法指针,界说类的办法时的两头查找表6(0x6)MethodDef形貌办法界说7(0x7)ParamPtr形貌参数指针,界说类的参数时的两头查找表8(0x8)ParamDef形貌办法的参数界说9(0x9)InterfaceImpl形貌有哪些范例完成了哪些接口10(0xa)MemberRef形貌援用成员的情形,援用成员能够是办法、字段另有属性。11(0xb)Constant形貌了参数、字段和属性的常数值12(0xc)CustomAttribute形貌了特征的界说13(0xd)FieldMarshal形貌了与非托管代码交互时,参数和字段的传送体例。14(0xe)DeclSecurity形貌了关于类、办法和程序集的平安性15(0xf)ClassLayout形貌类加载时的结构信息16(0x10)FieldLayout形貌单个字段的偏移或序号17(0x11)StandAloneSig形貌未被任何其他表援用的署名18(0x12)EventMap形貌类的事务列表19(0x13)EventPtr形貌了事务指针,界说事务时的两头查找表20(0x14)Event形貌事务21(0x15)PropertyMap形貌类的属性列表22(0x16)PropertyPtr形貌了属性指针,界说类的属性时的两头查找表23(0x17)Property形貌属性24(0x18)MethodSemantics形貌事务、属性与办法的联系关系25(0x19)MethodImpl形貌办法的完成26(0x1a)ModuleRef形貌内部模块的援用27(0x1b)TypeSpec形貌了对TypeDef大概TypeRef的申明28(0x1c)ImplMap形貌了程序集利用的一切非托管代码的办法29(0x1d)FieldRVA字段表的扩大,RVA给出了一个字段的原始值地位30(0x1e)ENCLog形貌在Edit-And-Continue形式中哪些元数据被修正过31(0x1f)ENCMap形貌在Edit-And-Continue形式中的映照32(0x20)Assembly形貌程序集界说33(0x21)AssemblyProcessor未利用34(0x22)AssemblyOS未利用35(0x23)AssemblyRef形貌援用的程序集36(0x24)AssemblyRefProcessor未利用37(0x25)AssemblyRefOS未利用38(0x26)File形貌内部文件39(0x27)ExportedType形貌在统一程序集但分歧模块,有哪些范例40(0x28)ManifestResource形貌资本信息41(0x29)NestedClass形貌嵌套范例界说42(0x2a)GenericParam形貌了泛型范例界说大概泛型办法界说所利用的泛型参数43(0x2b)MethodSpec形貌泛型办法的实例化44(0x2c)GenericParamConstraint形貌了每一个泛型参数的束缚
然后是6个定名堆:

申明

#String一个AscIIstring数组,被元数据表所援用,来暗示办法名、字段名、类名、变量名和资本相干字符串,但不包括stringliterals。#Blob包括元数据援用的二进制对象,但不包括用户界说对象#US一个unicodestring数组,包括了界说在代码中的字符串(stringliterals),这些字符串能够间接由ldstr指令加载猎取,还记得吗?我们在《第二十二回:字符串驻留(上)---带着成绩思索》中对字符串创立历程的叙述吗?#GUID保留了128byte的GUID值,由元数据表援用#~一个特别堆,包括了一切的元数据表,会援用其他的堆。#-一个未紧缩的#~堆。除#-堆,其他堆都是紧缩的。
Note:关于#String和#US,一个复杂的区分就是:
  1. stringhello="Hello,World";
复制代码
变量hello名,将保留在#String,而代码中字符串信息“Hello,World”则被保留在#US中。
关于元数据信息的具体形貌,比方每一个表包括哪些列,分歧表间的干系,请参考[StandardECMA-335]和[The.NETFileFormat]。
在PE文件格局中,Metadata有着庞大的布局,我试图以数据库办理数据的角度动身来了解元数据的布局和干系,以是暗示元数据的逻辑布局被成为元数据表,相似于数据库表有主键和Sechema,元数据表以RID(表索引)和元-元数据暗示类同的观点,以TypeDef表为例,经由过程数据援用干系同时与Field、Method、TypeRef等表产生联系关系,其他表间又有相似的干系,从而构成一个庞大的类数据库布局:

<br>
因而,元数据是保留了范例的编译后数据,是.NET程序运转的基本,我们能够在运转时静态的以反射的体例猎取元数据信息,而这些信息在.NETFramework中以System.Type、MethodInfo等封装,比方截取MSDN中一个类间干系的复杂示例:

<br>
关于每一个CLR范例而言都能够经由过程Object.GetType办法前往其Type,从而恣意的取到一切的运转时元数据信息:
  1. //Release:code04,2009/02/21//Author:Anytao,http://www.anytao.com//List:Program.csprivatestaticvoidShowMemberInfo(){varassems=AppDomain.CurrentDomain.GetAssemblies();foreach(Assemblyassinassems){foreach(Typetinass.GetTypes()){foreach(MemberInfomiint.GetMembers()){Console.WriteLine("Name:{0},Type:{1}",mi.Name,mi.MemberType.ToString());}}}}
复制代码
实行上述办法,将猎取一个长长的列表,看到良多熟习的标记:-)
4IL是甚么?
IL,又称为CIL大概MSIL,翻译为中文就是两头言语,由ECMA构造(StandardECMA-335)供应完全的界说和标准。望文生义,两头言语正如它的称号所言,任何与CLR兼容的编译器所天生的都是两头言语代码,这是完成CLR跨言语的基本布局之一。IL就像一座桥梁,其指令集自力于CPU指令而存在,能够由JIT编译器在运转时翻译为当地代码实行,毗连了任何恪守CLS标准的初级言语,为.NET平台供应了最基础的撑持。在[你必需晓得的.NET]一书中,我用一整章(第3章“统统从IL入手下手”)的篇幅对IL的基础内容举行了响应的先容,以是关于IL的基本内容比方基础范例、IL剖析办法、罕见指令、基础运算等,就不在本文有所赘述,只对IL基础内容举行一点小结:


  • IL是一种面向对象的呆板言语,因而具有面向对象言语的一切特征,类、对象、承继、多态等仍旧是IL言语的基础观点。
  • IL指令自力于CPU指令,CLR经由过程JIT编译机制将其转换为当地代码。
  • IL和元数据是懂得CLR运转机制的主要内容,关于我们翻开CLR奥秘面纱有侧重要的意义。
如前文[初度打仗]部分叙述的一样,能够经由过程ILDasm.exe大概Reflector工具对托管代码实行反编译来检察其IL代码,关于良多情形下IL代码剖析能够办理良多初级言语埋没的语法糖游戏,比方C#3.0提出的主动属性、隐式范例、匿名范例、扩大办法等都能够很快从IL剖析中找到谜底,以是得当的懂得IL是需要的。那末我们鄙人面JIT编译时的一个片断来懂得IL代码关于托管程序实行的感化。
别的,Metadata形貌了静态的布局,而IL阐释了静态的实行,而IL代码是经由过程一个4字节巨细的地点援用元数据表的。该援用被称为元数据标记(MetadataToken,也就是纪录元数据表的地位信息),在ILdasm.exe工具当选中“Showtokenvalues”,就能够在IL代码中看到IL代码经由过程MetadataToken援用元数据表的情形:
  1. .method/*06000003*/privatehidebysigstaticvoidMain(string[]args)cilmanaged{.entrypoint//Codesize36(0x24).maxstack2.locals/*11000002*/init([0]int32id,[1]classAnytao.Insidenet.MetadataIL.One/*02000004*/one,[2]classAnytao.Insidenet.MetadataIL.Two/*02000002*/two)IL_0000:nopIL_0001:ldc.i4.1IL_0002:stloc.0IL_0003:newobjinstancevoidAnytao.Insidenet.MetadataIL.One/*02000004*/::.ctor()/*06000007*/IL_0008:stloc.1IL_0009:ldloc.1IL_000a:ldloc.0IL_000b:callvirtinstancevoidAnytao.Insidenet.MetadataIL.One/*02000004*/::set_ID(int32)/*06000006*/IL_0010:nopIL_0011:newobjinstancevoidAnytao.Insidenet.MetadataIL.Two/*02000002*/::.ctor()/*06000002*/IL_0016:stloc.2IL_0017:ldloc.2IL_0018:callvirtinstancestringAnytao.Insidenet.MetadataIL.Two/*02000002*/::SayHello()/*06000001*/IL_001d:callvoid[mscorlib/*23000001*/]System.Console/*01000012*/::WriteLine(string)/*0A000011*/IL_0022:nopIL_0023:ret}//endofmethodProgram::Main
复制代码
个中,依照ECMA界说的标准,元数据第一个字节暗示援用的元数据表,而其他三个字节则暗示在响应元数据表中的纪录,比方06000003暗示了援用了MethodDef(06)表的000003项Main办法。
我们能够经由过程Type的MetadataToken属性在运转时反射猎取范例的元数据标记,比方:
  1. staticvoidMain(string[]args){Console.WriteLine(typeof(One).MetadataToken);}
复制代码
有了上述一切的筹办,我们就能够动手剖析元数据和IL在程序实行时的脚色和联系关系。

<br>欲知后事怎样,且听下文持续:-)

  • 《第二十四回:熟悉元数据和IL(上)》元数据和IL在JIT编译时
参考文献


  • 《你必需晓得的.NET》第3章“统统从IL入手下手”
  • DonBox,《.NET实质论》
  • http://www.sloppycode.net/articles/inside-net-assemblies-and-metadata.aspx
  • http://www.codeproject.com/KB/dotnet/dotnetformat.aspx
来自:http://www.ckuyun.com/anytao/archive/2009/02/25/must_net_25.html
net网页编程欺骗了我们那么多年,如今的多核时代,我认为它气数已尽!
柔情似水 该用户已被删除
沙发
发表于 2015-1-19 21:38:09 | 只看该作者
市场决定一切,我个人从经历上觉得两者至少在很长时间内还是要共存下去,包括C和C++,至少从找工作就看得出来,总不可能大家都像所谓的时尚一样,追捧一门语言并应用它。
乐观 该用户已被删除
板凳
发表于 2015-1-20 18:15:10 | 只看该作者
这也就是最近几年来随着各种新的后台技术的诞生,CGI应用在Internet上越来越少的原因。CGI方式不适合大访问量的应用。
若天明 该用户已被删除
地板
发表于 2015-1-25 11:31:58 | 只看该作者
ASP.NET可以无缝地与WYSIWYGHTML编辑器和其他编程工具(包括MicrosoftVisualStudio.NET)一起工作。这不仅使得Web开发更加方便,而且还能提供这些工具必须提供的所有优点,包括开发人员可以用来将服务器控件拖放到Web页的GUI和完全集成的调试支持。微软为ASP.net设计了这样一些策略:易于写出结构清晰的代码、代码易于重用和共享、可用编译类语言编写等等,目的是让程序员更容易开发出Web应用,满足计算向Web转移的战略需要。
老尸 该用户已被删除
5#
发表于 2015-1-26 21:09:58 来自手机 | 只看该作者
我的意思是.net好用,从功能上来说比JAVA强还是很明显的。
莫相离 该用户已被删除
6#
发表于 2015-2-4 20:31:55 | 只看该作者
是指转换后的Servlet程序代码的行数。这给调试代码带来一定困难。所以,在排除错误时,可以采取分段排除的方法(在可能出错的代码前后输出一些字符串,用字符串是否被输出来确定代码段从哪里开始出错)。
再现理想 该用户已被删除
7#
发表于 2015-2-5 22:25:44 | 只看该作者
但是目前在CGI中使用的最为广泛的是Perl语言。所以,狭义上所指的CGI程序一般都是指Perl程序,一般CGI程序的后缀都是.pl或者.cgi。
蒙在股里 该用户已被删除
8#
发表于 2015-2-22 22:13:37 | 只看该作者
可以通过在现有ASP应用程序中逐渐添加ASP.NET功能,随时增强ASP应用程序的功能。ASP.NET是一个已编译的、基于.NET的环境,可以用任何与.NET兼容的语言(包括VisualBasic.NET、C#和JScript.NET.)创作应用程序。另外,任何ASP.NET应用程序都可以使用整个.NETFramework。开发人员可以方便地获得这些技术的优点,其中包括托管的公共语言运行库环境、类型安全、继承等等。
精灵巫婆 该用户已被删除
9#
发表于 2015-3-6 11:22:24 | 只看该作者
ASP.net的服务器,要求安装一个.net环境,当然我这里指的是windows系统,顺便点一下,.net只能放在windows环境里来运行。Asp.net1.1的就装Framework1.1,Asp.net2.0的就装Framework2.0。
冷月葬花魂 该用户已被删除
10#
发表于 2015-3-10 19:51:18 | 只看该作者
当然我们在选择Asp.net主机是,除了要考虑服务提供商在版本是否是实时更新以外,机房的环境和配置也是非常重要的,通常选择骨干网的机房,在速度和稳定性上会非常有保证。
变相怪杰 该用户已被删除
11#
发表于 2015-3-17 09:17:47 | 只看该作者
那么,ASP.Net有哪些改进呢?
透明 该用户已被删除
12#
发表于 2015-3-24 05:51:56 | 只看该作者
JSP/Servlet虽然在国内目前的应用并不广泛,但是其前途不可限量。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-12-23 17:52

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表