ASP.NET网站制作之[你必需晓得的.NET]第二十四回:熟悉元数据和IL(上)仓酷云
也许唯一可以让世人留恋net网页编程的理由就剩下它的王牌——跨平台。系列文章目次索引:《你必需晓得的.NET》<br>说在,开篇之前很早就有说说Metadata(元数据)和IL(两头言语)的设法了,一向在这篇入手下手才算兢兢业业的对这两个阶层兄弟投往些细关切,固然来得没有《第一回:恩仇情仇:is和as》那末敏捷,可是Metadata和IL倒是相对分量级的内容,值得我们在任什么时候间存眷,本文就是入手下手。1弁言你可曾想到,我们的C#代码,编译以后事实为什么物?你可曾认知,我们的可实行程序,运转之时的轨迹事实为哪般?那末,本文经由过程对Metadata(元数据)和IL(IntermediateLanguage,两头言语)的熟悉入手下手,来慢慢给出谜底。在这个探究轨迹上,元数据、IL、程序集、程序域、JIT、虚分拨、办法表和托管堆这些五花八门的奥秘佳宾将在某个时候萍水相逢,作为你必需晓得的.NET系列2.0版本的一部分,本文起首从熟悉元数据和IL这两位分量级选手入手下手,而其他的佳宾也将很快退场。
2初度打仗
在现实上,编译以后的cs代码被构造为两种基础的元素:元数据(Metadata)和IL。我们能够以最复杂的体例来懂得程序集(*.dll)或可实行文件(*.exe)中包括的Metadata和IL的奥密,这类体例就是我们常说的反编译,翻开ILDasm并加载完成筹办的程序集,我们能够看到托管PE文件的相干内容:
<br>
具体的布局信息和IL代码剖析,能够拜见[你必需晓得的.NET]第3章“统统从IL入手下手”的先容,在此就不做太多的剖析。别的,我们能够经由过程实行“View/MetaInfo/Show!”大概Ctrl+M快速键来猎取该程序集所利用的MetaData信息列表:
个中该程序集利用的元数据次要有:Module、TypeRef、TypeDef、Method、Param、MemberRef、CostomAttribute、Assembly、AssemblyRef等,同时还包含#Strings、#GUID、#Blob、#US堆等。
固然,关于ILDasm工具,另有良多好玩的利用体例来满意我们探究IL代码的猎奇心,比方:
<br>ildasmAnytao.Insidenet.MetadataIL.exe/output:my.il,将反编译了局导出为il代码格局,天生一个my.il包括了一切的IL代码和一个my.res包括了一切的资本文件。
<br>ildasmAnytao.Insidenet.MetadataIL.exe/text,将反编译了局以Console情势输入。
固然我们仍是保举以GUI情势来检察IL细节,构造布局优秀的ClassView:
<br>ildasmAnytao.Insidenet.MetadataIL.exe
上面起首给出介入编译的相干代码文件,然后再睁开我们对Metadata和IL的会商:
//Release:code01,2009/02/12
//Author:Anytao,http://www.anytao.com
//List:One.cs
publicclassOne
{
publicintID{get;set;}
}//Release:code02,2009/02/12
//Author:Anytao,http://www.anytao.com
//List:Two.cs
publicclassTwo
{
publicstringSayHello()
{
return"Hello,world.";
}
}//Release:code03,2009/02/12
//Author:Anytao,http://www.anytao.com
//List:Program.cs
classProgram
{
staticvoidMain(string[]args)
{
intid=1;
Oneone=newOne();
one.ID=id;
Twotwo=newTwo();
Console.WriteLine(two.SayHello());
}
}接着,我们对上述程序的编译实行历程举行一点探究,以命令行编译器来演变其大抵的编译历程,以此进一步懂得托管模块,程序集和可实行文件之间的干系:
[*]翻开VisualStudio2008CommandPrompt,并定位到cs代码地点文件夹,编译One.cs为托管模块,实行命令:
<br>csc/t:moduleOne.cs
实行以后,将天生名为One.netmodule文件;
[*]持续实行,将多个模块打包为程序集
<br>csc/t:library/addmodule:One.netmoduleTwo.cs实行以后,将天生名为Two.dll文件;
[*]最初,编译Main函数和Two.dll为可实行文件
<br>csc/out:Anytao.Insidenet.MetatdataIL.exe/t:exe/r:Two.dll/r:mscorlib.dllProgram.cs终极将失掉本文入手下手时所加载的用于反编译的程序集文件Anytao.Insidenet.MetadataIL.exe,在该实行命令中对几个唆使符开关做点申明:
[*]/out:Anytao.Insidenet.MetadataIL.exe,暗示输入的可实行文件,及其称号
[*]/t:exe,暗示输入的文件范例为CUI(把持台界面程序)程序;而/t:winexe,暗示输入为GUI(图形界面程序)程序
[*]/r:Two.dll,暗示援用方才临盆的Two.dll程序集
[*]/r:mscorlib.dll,暗示由于内部程序集mscorlib.dll,由于我们的程序中利用了Console静态办法,而该办法则被界说在mscorlib.dll中。mscorlib.dll是云云的主要,我们将在本文以后的某些时分再次与mscorlib.dll握手,当时在对其举行一个具体的剖析,敬请等候。
在cmd中的实行历程能够参考:
<br>
经由过程分步实行的体例我们对csc编译器的实行历程有个基础的懂得,也同时从正面熟悉了每次在VisualStudio中实行“Build“大概“ReBuild”的缩影。综上剖析,我们能够复杂的看到:
Note:在VisualStudio中,编译是分模块举行的,编译了局保留在obj目次中,最初再兼并为可实行文件于bin目次,同时默许情形下,编译历程是增量式的,仅编译产生修正的模块,我将在后文给出较为具体的历程。
同时,我们还能够劳绩以下几个基础的结论:
[*]cs代码编译以后将天生元数据和IL,并构成托管模块(Module)的基础单位。
[*]多个托管模块构成程序集,实在还包含必定的资本文件,只是没有在此表现。
[*]程序集大概可实行文件是逻辑构造的基础单位,切合基础的WindowsPE文件格局,能够被x86大概x64Windows间接加载实行。
3持续深切
一个大概多个模块,再加上资本文件就构成了程序集(Assembly),作为逻辑构造的基础单位,
<br>
现实上,此图仅仅从粗粒度对程序集的基础构成有个大抵的懂得,实践上程序会合包括了庞大的布局和要素,比方PESignature、ManagedResources、StrongNameSignatureHash,而个中最中心的要素则表现在上图。
[*]程序集清单(MANIFEST)包括了程序集的自形貌信息,次要包括AssemblyDef、FileDef、ManifestResourceDef和ExportedTypeDef,在反编译选项中MANIFEST包括了具体的内容。在《你必需晓得的.NET》3.1节“从Hello,world入手下手熟悉IL”对其有过具体的形貌,此不赘述。
[*]PE文件头,尺度WindowsPE头文件(PE32或PE32+),PE文件的基础信息,比方文件范例,创立工夫,当地CPU信息等。
[*]CLR头,包括CLR版本、模块元数据、资本等信息。
[*]资本文件。
实行View/Statisctics菜单,能够翻开相干的统计信息:
Filesize:5632
PEheadersize:512(496used)(9.09%)
PEadditionalinfo:1691(30.02%)
Num.ofPEsections:3
CLRheadersize:72(1.28%)
CLRmeta-datasize:2212(39.28%)
CLRadditionalinfo:0(0.00%)
CLRmethodheaders:52(0.92%)
Managedcode:287(5.10%)
Data:2048(36.36%)
Unaccounted:-1242(-22.05%)
Num.ofPEsections:3
.text-3072
.rsrc-1536
.reloc-512
CLRmeta-datasize:2212
Module-1(10bytes)
TypeDef-4(56bytes)0interfaces,0explicitlayout
TypeRef-25(150bytes)
MethodDef-8(112bytes)0abstract,0native,8bodies
FieldDef-1(6bytes)0constant
MemberRef-29(174bytes)
ParamDef-2(12bytes)
CustomAttribute-16(96bytes)
StandAloneSig-4(8bytes)
PropertyMap-1(4bytes)
Property-1(6bytes)
MethodSemantic-2(12bytes)
Assembly-1(22bytes)
AssemblyRef-1(20bytes)
Strings-920bytes
Blobs-328bytes
UserStrings-68bytes
Guids-16bytes
Uncategorized-192bytes
CLRmethodheaders:52
Num.ofmethodbodies-8
Num.offatheaders-4
Num.oftinyheaders-4
Managedcode:287
Avemethodsize-35
我们将在后篇《深切程序集和模块》中对PE头,CLR头和资本文件举行具体叙述。
[*]IL代码被构造为
.classpublicautoansibeforefieldinitAnytao.Insidenet.MetadataIL.Two
extendsSystem.Object
{
.methodpublichidebysiginstancestring
SayHello()cilmanaged
{
//Codesize11(0xb)
.maxstack1
.localsinit(stringCS$1$0000)
IL_0000:nop
IL_0001:ldstr"Hello,world."
IL_0006:stloc.0
IL_0007:br.sIL_0009
IL_0009:ldloc.0
IL_000a:ret
}//endofmethodTwo::SayHello
.methodpublichidebysigspecialnamertspecialname
instancevoid.ctor()cilmanaged
{
//Codesize7(0x7)
.maxstack8
IL_0000:ldarg.0
IL_0001:callinstancevoidSystem.Object::.ctor()
IL_0006:ret
}//endofmethodTwo::.ctor
}//endofclassAnytao.Insidenet.MetadataIL.Two包装在相似于汇编容貌的外套下,我看模糊可见class,System.Object,method,public,string这些面向对象初级言语中的熟习面目面貌,分歧的只是多了良多benforefieldinit(参考:[你必需晓得的.NET]第二十三回:咀嚼细节,深切.NET的范例机关器),ret,maxstack,ldstr,stloc这些生疏的指令。但是IL并不是一个怪胎,而恰是基于其自己面向对象的汇编式作风,才作育了IL代码成为名不虚传的“两头言语”的重担。经由过程IL代码,CLR便可在编译时由JIT编译转换为NativeCode,我们将鄙人节持续剖析这个历程的前因后果。
<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/24/must_net_24.html
因为二次编译器太复杂,那么建议只是在安装程序的时候编译一次,而不类似net网页编程那样运行就编译。并且我觉得,一次痛苦,总比多次低效率要舒服多了。 能产生和执行动态、交互式、高效率的站占服务器的应用程序。运用ASP可将VBscript、javascript等脚本语言嵌入到HTML中,便可快速完成网站的应用程序,无需编译,可在服务器端直接执行。容易编写。 由于JSP/Servlet都是基于Java的,所以它们也有Java语言的最大优点——平台无关性,也就是所谓的“一次编写,随处运行(WORA–WriteOnce,RunAnywhere)”。除了这个优点,JSP/Servlet的效率以及安全性也是相当惊人的。 同时也感谢博客园给我们这个平台,也感谢博客园的编辑们做成专题引来这么多高人指点。 市场决定一切,我个人从经历上觉得两者至少在很长时间内还是要共存下去,包括C和C++,至少从找工作就看得出来,总不可能大家都像所谓的时尚一样,追捧一门语言并应用它。 CGI程序在运行的时候,首先是客户向服务器上的CGI程序发送一个请求,服务器接收到客户的请求后,就会打开一个新的Process(进程)来执行CGI程序,处理客户的请求。CGI程序最后将执行的结果(HTML页面代码)传回给客户。 在调试JSP代码时,如果程序出错,JSP服务器会返回出错信息,并在浏览器中显示。这时,由于JSP是先被转换成Servlet后再运行的,所以,浏览器中所显示的代码出错的行数并不是JSP源代码的行数。 大哥拜托,Java在95年就出来了,微软垄断个妹啊,服务器市场微软完全是后后来者,当年都是Unix的市场,现在被WindowsServer和Linux抢下大片,包括数据库也一样。 ASP.net的速度是ASP不能比拟的。ASP.net是编译语言,所以,当第一次加载的时候,它会把所有的程序进行编译(其中包括worker进程,还有对语法进行编译,形成一个程序集),当程序编译后,执行速度几乎为0。 以上是语言本身的弱点,在功能方面ASP同样存在问题,第一是功能太弱,一些底层操作只能通过组件来完成,在这点上是远远比不上PHP/JSP,其次就是缺乏完善的纠错/调试功能,这点上ASP/PHP/JSP差不多。 ASP(ActiveServerPages)是Microsfot公司1996年11月推出的WEB应用程序开发技术,它既不是一种程序语言,也不是一种开发工具,而是一种技术框架,不须使用微软的产品就能编写它的代码。
页:
[1]