分享
 
 
 

Delphi.NET 内部实现分析(1)

王朝delphi·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

Delphi.NET 内部实现分析

Delphi.NET 内部实现分析(1)

Delphi.NET 内部实现分析

0.概述

自M$发布.NET以来,业界厂商态度大相径庭。但不可否认的是,

在M$雄厚实力和充足资金的保障下.NET架构已经逐渐站稳脚跟,

开始向Java等既得利益者发起冲击。

而作为开发工具领跑者的Borland公司,也于2002年末,

伴随其并没有太大新意的Delphi 7,一同发布了Delphi.NET预览版。

本文就是基于这个预览版本,针对其内部实现原理进行分析,

帮助读者在了解Delphi的基础上,过渡到.NET时代。

1. Hello Delphi!

1.1. 初见 Delphi.NET

在详细分析Delphi.NET实现之前,让我们先从感性上认识一下它:

//-----------------------------------------HelloWorld.dpr--

Program HelloWorld;

{$APPTYPE CONSOLE}

begin

Writeln('Hello Delphi!');

end.

//-----------------------------------------HelloWorld.dpr--

看上去是否很眼熟?没错,这是一个标准的Delphi控制台程序,

同时也可以直接使用Delphi.NET编译成一个真正的.NET程序

E:\Borland\Delphi.Net\demos\Hello>dccil HelloWorld.dpr

Borland Delphi Version 16.0

Copyright (c) 1983,2002 Borland Software Corporation

Confidential pre-release version built Nov 14 2002 17:05:31

HelloWorld.dpr(8)

9 lines, 0.28 seconds, 4816 bytes code, 0 bytes data.

E:\Borland\Delphi.Net\demos\Hello>peverify HelloWorld.exe

Microsoft (R) .NET Framework PE Verifier Version 1.0.3705.0

Copyright (C) Microsoft Corporation 1998-2001. All rights reserved.

All Classes and Methods in HelloWorld.exe Verified

E:\Borland\Delphi.Net\demos\Hello>HelloWorld

Hello Delphi!

先使用 dccil,Borland经典Delphi编译器DCC32的IL版本,

将Delphi的Object Pascal代码编译成.NET架构的IL中间语言文件,

类似Java中的ByteCode;

再使用.NET Framework SDK附带的peverify验证程序有效性,

确认此HelloWorld.exe的确是.NET兼容的程序;

最后运行HelloWorld.exe程序,得到我们期望的结果。

看上去很美……不是吗?

不过在这看上去简单的代码背后,Borland做了大量底层工作,提供Delphi在.NET架构上

最大限度的源代码级兼容性,甚至不惜增加新语言特性(Delphi从Delphi3/4开始,语法上就

已经很稳定了,或者说已经很成熟了)。

1.2. 结构

用.NET Framework SDK附带的ILDASM工具打开HelloWorld.exe文件,

可以看到有两个名字空间Borland.Delphi.System和HelloWorld存在,

而MANIFEST里面是配件(Assembly)一级信息,详细含义请参加笔者另一系列文章

《MS.Net CLR扩展PE结构分析》,里面有详细解析。(.NET是M$的.NET架构的名称,

在实现一级其程序运行在CLR Common Language Runtime的环境中,类似Java中

虚拟机VM的概念,因此下文中对实现一级不再以.NET而以CLR称呼)

与Delphi一样,Delphi.NET自动引用System单元的内容,只不过单元名称

变成了Borland.Delphi.System而已。这是Object Pascal增加的语言特性之一

——命名空间(namespace),用于将类定义隔离在不同作用域中,以避免名字冲突。

而HelloWorld命名空间则是根据项目或单元名称自动生成的,实际代码一般保存在此

命名空间的类中。

我们先来看看代码所在的HelloWorld名字空间

.namespace HelloWorld

{

.class /*0200000B*/ public auto ansi Unit

extends [mscorlib/* 23000001 */]System.Object/* 01000001 */

{

...

} // end of class Unit

} // end of namespace HelloWorld

HelloWorld名字空间中只定义了一个Unit类。Delphi.NET中,每一个单元(Unit)

都在自己的命名空间下有一个自动生成的Unit类,用于实现全局变量、全局函数等等特性。

因为CLR中是不存在独立于类之外的元素的,所有元素都必须以类形式组织,所以对Delphi.NET/C++

之类支持全局变量、函数的语言,必须用一个自动生成的伪类来包装。Delphi.NET为每个单元

生成一个Unit类,Managed C++等语言中则使用其它诸如<Module>之类的名字。

因为我们的HelloWorld.dpr中没有定义自己的类,直接使用函数,所以在HelloWorld命名空间中,

只有一个Unit类,内容如下

.namespace HelloWorld

{

.class /*0200000B*/ public auto ansi Unit

extends [mscorlib/* 23000001 */]System.Object/* 01000001 */

{

.method /*06000027*/ private hidebysig specialname rtspecialname static

void .cctor() cil managed

.method /*06000025*/ public hidebysig specialname rtspecialname

instance void .ctor() cil managed

.method /*06000026*/ public hidebysig static void $WakeUp() cil managed

.method /*06000023*/ public static void Finalization() cil managed

.method /*06000024*/ public static void HelloWorld() cil managed

}

}

其中.cctor()和.ctor()函数分别是类Unit的静态/动态构造函数,负责对Unit

进行类和对象一级的构造工作。

对Delphi来说,构造函数所在级别是介于类和对象之间的。

TMyClass = class

public

constructor Create;

end;

var

Obj: TObject;

begin

Obj := TMyClass.Create;

try

//...

finally

FreeAndNil(Obj);

end;

end;

这里的Create由constructor关键字定义为构造函数,实现上类似类函数

(class function),隐含传入一个指向其元类(MetaClass)的指针和一个标志,

相对的普通成员函数隐含传入一个指向其实例的指针,也就是众所周知的Self。

而在构造函数中,调用时类似调用类函数传入其元类指针,函数中由编译器自动添加

_ClassCreate函数调用TObject.NewInstance分配内存并初始化对象,

将Self改为指向真正的对象。

在Delphi.NET中,.ctor()类似于Delphi中的构造函数,用于在分配内存空间后

构造对象实例,其被调用时,对象所需内存已经分配完毕,所有成员变量被初始化为

0、false或null。也就是说Delphi中构造函数的功能在CLR中被分为两部分,

分配和初始化内存功能由IL指令newobj完成,调用用户代码初始化对象功能由其构造函数

被newobj或initobj指令调用完成,前者用于在堆中分配并初始化对象,后者用于

调用构造函数初始化在堆栈上分配好的内存。

而.cctor()则是CLR中特有的静态构造函数概念,其代码由CLR保证在此类的任意成员

被使用之前调用,初始化类的静态成员。因而可以存在至多一个不使用参数的静态构造函数。

因为.ctor()和.cctor()函数都是有CLR内部使用的,因而定义其函数标志为

hidebysig specialname rtspecialname,分别表示此函数以函数整个定义而并非

仅仅以名字来区分,避免命名冲突;函数名对系统和CLR有特殊意义。

详细介绍请参加笔者另一系列文章《MS.Net CLR扩展PE结构分析》,里面有详细解析.

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有