Delphi.NET 内部实现分析(1,2,3)(转贴)
2005-12-31 13:14
459 查看
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结构分析》,里面有详细解析。
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结构分析》,里面有详细解析。
[align=center]作者:潇潇2003 发表时间:2004-12-21 10:37[/align] |
[align=left]本贴地址:http://club.yesky.com/bbs/jsp/view.jsp?articleID=1069270[/align] |
Delphi.NET 内部实现分析(2)(转贴 Unit类中剩下三个方法$WakeUp()由Delphi.NET内部使用;Finalization()完成 类似Delphi单元中finalization节的功能;最后一个HelloWorld()函数也是自动生成, 使用Unit类所在名字空间名称命名,如这里的HelloWorld,完成类似Delphi单元中 initialization节的功能,如在.dpr中则完成begin end.之间的程序功能。 从CLR角度来看,在载入Delphi.NET编译的配件后,通过Metadata定位到缺省指向的类 调用类的静态构造函数(即本例中的HelloWorld.Unit..cctor()函数),调用类的Main函数 (即本例中的HelloWorld.Unit.HelloWorld()方法)。 在程序入口类的静态构造函数.cctor中,要完成挂接Unit析构函数(本例中 HelloWorld.Unit.Finalization()函数)到系统一级终结调用列表上的工作。 HelloWorld.Unit..cctor中的伪代码如下 unit HelloWorld type Unit = class procedure .cctor(); proceudre HelloWorld(); ... implementation procedure Unit..cctor(); begin Borland.Delphi.System.Unit._AddFinalization( new Borland.Delphi.System._FinalizeHandler( null, HelloWorld.Unit.Finalization)); HelloWorld.Unit.HelloWorld(); end; HelloWorld.Unit.Finalization方法是HelloWorld.Unit类的finalization节 代码所在,用于在单元卸载时析构;Borland.Delphi.System._FinalizeHandler是 Borland.Delphi.System单元中定义的一个事件委托类型(Delegate); Borland.Delphi.System.Unit._AddFinalization则是Borland.Delphi.System单元 的一个全局函数_AddFinalization。 在Borland.Delphi.System单元中可以看到其实现代码 //-----------------------------------------Borland.Delphi.System.pas-- type _FinalizeHandler = procedure of object; var OnProcessExit: _FinalizeHandler; procedure _AddFinalization(f: _FinalizeHandler); begin OnProcessExit := _FinalizeHandler(System.Delegate.Combine( System.Delegate(@f), System.Delegate(@OnProcessExit))); end; {$IF SimpleFinalizer} type TFinalObject = class public procedure Finalize; override; end; procedure TFinalObject.Finalize; begin OnProcessExit; inherited; end; {$ELSE} procedure ProcessExitHook(sender: System.Object; eventArgs: System.EventArgs); begin OnProcessExit; end; {$IFEND} {$IF SimpleFinalizer} var _GlobalFinalObject: TObject; {$IFEND} initialization {$IF SimpleFinalizer} {$MESSAGE WARN 'Using simple finalizer'} _GlobalFinalObject := TFinalObject.Create; {$ELSE} System.AppDomain.CurrentDomain.add_ProcessExit(ProcessExitHook); // System.AppDomain.CurrentDomain.add_ProcessExit( // System.EventHandler.Create(nil, IntPtr(@ProcessExitHook))); {$IFEND} //-----------------------------------------Borland.Delphi.System.pas-- 首先事件委托类型_FinalizeHandler的定义,和Delphi中定义类成员函数指针语法相同。 在Delphi中,此类指针实现上是以一个TMethod结构存在的,分别保存对象实例和成员函数的指针, 这与普通C/C++语言中的函数指针大相径庭。 //-----------------------------------------System.pas-- TMethod = record Code, Data: Pointer; end; //-----------------------------------------System.pas-- 而在CLR中事件的实现与Delphi非常类似(毕竟是同一个人设计的:),只不过用类包装了一下罢了, 具体讲解参见牛人Jeffrey Richter的《MS .NET Framework 程序设计》一书。 因此在Delphi.NET中对事件处理函数的定义可以原封不动。 与Delphi不同的是,CLR中的Deltegate可以同时由多个处理函数订阅,在C#一类直接支持事件的 语言中直接表述为 OnProcessExit += new _FinalizeHandler(...) 即可,而在Delphi.NET中 只好用_AddFinalization函数中这类精确的函数调用,希望Borland能在以后给Delphi.NET加上类似 C#语言中的表述语法,这样跟清晰明了一些,要是有运算符重载就跟爽了,反正底层都是用CLR实现。 接着Delphi.NET提供了两种实现单元一级finalization功能的方法 定义SimpleFinalizer的话,就使用较为简单的方法,直接由_GlobalFinalObject对象管理生命周期。 因为_GlobalFinalObject对象是一个全局对象,其生命期贯串整个程序,当其被释放时整个程序也就结束了。 而TFinalObject重载了Finalize方法,此方法如果被重载,则GC 垃圾回收在释放对象之前,会调用此方法。 这样就保证所有单元的finalization节在Borland.Delphi.System单元卸载之前,通过注册的析构事件 OnProcessExit被依次调用。 如果不定义SimpleFinalizer的话,则使用较复杂的方法。通过ProcessExitHook函数挂接到当前 AppDomain 应用程序域的进程结束事件上,在进程结束之前依次调用。 在挂接完析构处理函数后,.cctor会调用HelloWorld()指向单元初始化代码或程序执行代码。 如在本例中调用HelloWorld.Unit.HelloWorld()函数 public static void HelloWorld() { Borland.Delphi.System.Unit.$WakeUp(); Borland.Delphi.System.Unit._WriteLn( Borland.Delphi.System.Unit._Write0WString( Borland.Delphi.System.Unit.Output, "Hello Delphi!")); Borland.Delphi.System.Unit.__IOTest(); } 前后的$WakeUp()和__IOTest()分别负责唤醒和IO测试,目前没有什么作用。 中间的代码就是Writeln('Hello Delphi!');这行代码的实现,等我们具体解析 Borland.Delphi.System单元时再作评述。 1.3 类的实现 在分析了一个最简单的Delphi.NET程序后,我们来看看复杂一些的例子。 这个例子中定义了一个TDemo类,完成和上个例子相同的功能,只不过在类中完成。 //-----------------------------------------HelloWorld2.dpr-- Program HelloWorld; {$APPTYPE CONSOLE} type TDemo = class public procedure Hello; end; { TMemo } procedure TDemo.Hello; begin Writeln('Hello Delphi!'); end; begin TDemo.Create.Hello; end. //-----------------------------------------HelloWorld2.dpr-- 用ILDASM打开HelloWorld2.exe,可以发现在HelloWorld名字空间中增加了 一个TDemo类,HelloWorld.Unit.HelloWorld()函数中的代码也改为了 public static void HelloWorld() { Borland.Delphi.System.Unit.$WakeUp(); new HelloWorld.TDemo().Hello(); } 接着我们来看看TDemo这个类的实现。 我们会发现TDemo是直接从System.Object类继承出来的。 在传统的Delphi语言中,如果在定义一个类的时候不显式指定其父类,则隐式将其父类 指定为TObject类;而在Delphi.NET中,因为要让系统架构融入CLR的标准类库的架构中, 不可能再为Delphi.NET定义一套继承树,所以所有TObject都变为了System.Object。 为最大限度兼容原有代码中的TObject,Delphi.NET中引入了class helper这个重要概念。 class helper这个概念可以说是一种非常巧妙的妥协,它允许用户向现有类树的结点 从外部添加新功能,但限定不能增加数据成员。因为Borland要将其VCL架构移植到CLR的BCL上, 虽然BCL和VCL结构上非常类似(本来就是一个人设计的),但从名字到功能都有一些细节上的差异, 而Borland没有BCL的源代码,M$也不可能允许其它厂商修改其源代码。这就造成了Borland的悖论, 要在无法修改BCL架构的情况下修改其架构来支持VCL,呵呵。 妥协的结果就是class helper这种补丁语法的出现。 之所以说是补丁语法,是因为class helper允许在不修改现有类的基础上,将新功能添加到其上。 而class helper又限定不能增加数据成员,这样就不会因为改变原有类的物理结构导致程序变动。 这样的效果形象地说来就是给原有类打上一个补丁,让原有的BCL的类无论看上去还是使用起来都很像 VCL的对应类。 例如在Delphi.NET中,TObject类型实际上就是System.Object的一个别名。 而TObjectHelper作为TObject的补丁,为TObject提供兼容VCL中TObject的函数, 这些函数实现上都是通过System.Object的方法完成的,只是名字和用法不同。 //-----------------------------------------Borland.Delphi.System.pas-- type TObject = System.Object; TObjectHelper = class helper for TObject procedure Free; function ClassType: TClass; class function ClassName: string; class function ClassNameIs(const Name: string): Boolean; class function ClassParent: TClass; class function ClassInfo: TObject; class function InheritsFrom(AClass: TClass): Boolean; class function MethodAddress(const Name: string): TObject; class function SystemType: System.Type; function FieldAddress(const Name: string): TObject; procedure Dispatch(var Message); end; //-----------------------------------------Borland.Delphi.System.pas-- 这样一来,Borland就简洁但并不完美的解决了这个悖论。不过可以预见,这种语法的出现, 必将在将来引发激烈的争论,因为无论如何,这种语法事实上冲击了OO设计思想的纯洁性。 后面我们分析Borland.Delphi.System单元时再详细讨论class helper的使用方法。 在TDemo类中,另一个值得注意的是名为@MetaTDemo的嵌套子类。 在Delphi中,每个类都有一个对应的元类 MetaClass,可以通过class of TMyClass定义 TMyClass的元类类型来访问,也可以从类方法中直接通过Self指针访问。元类在实现上就是在 此类对象所共有的VMT表。 而在Delphi.NET中,类的内存布局不再由Delphi完全控制,不大可能将VMT再绑定到每个对象上。 所以Borland通过一个以"@Meta+类名"作为类名称的嵌套子类来表示此类的元类。如TDemo的元类是 TDemo.@MetaTDemo类,从Borland.Delphi.System._TClass类继承出来。 //-----------------------------------------Borland.Delphi.System.pas-- _TClass = class; TClass = class of TObject; _TClass = class protected FInstanceType: System.RuntimeTypeHandle; FClassParent: _TClass; public constructor Create; overload; constructor Create(ATypeHandle: System.RuntimeTypeHandle); overload; constructor Create(AType: System.Type); overload; function ClassParent: TClass; virtual; end; TClassHelperBase = class(TObject) public FInstance: TObject; end; //-----------------------------------------Borland.Delphi.System.pas-- 所有的元类如TDemo.@MetaTDemo类,都是继承自_TClass类,并使用类似TClassHelperBase的实现。 如TDemo.@MetaTDemo类就是以类似这样的伪代码定义的,只不过FInstance是静态成员变量 TDemo = class(TObject) public @MetaTDemo = class(_TClass) public FInstance: TObject; // static class constructor StaticCreate; constructor Create; ... end; class constructor TDemo.@MetaTDemo.StaticCreate; begin FInstance := @MetaTDemo.Create; // normal constructor end; constructor TDemo.@MetaTDemo.Create; begin inherited; inherited FInstanceType := token of HelloWorld.TDemo; end; 在@MetaTDemo的静态构造函数中,将@MetaTDemo.FInstance初始化为自身的实例; 在@MetaTDemo的构造函数中,将其表示类的Token放入_TClass.FInstanceType中, 我们后面分析Borland.Delphi.System单元时再详细解释。 这一小节我们大概了解了Delphi.NET是如何为原有Delphi类在源代码一级提供兼容性的, 分析了class helper和元类 MetaClass的实现原理。下一节我们将开始分析Delphi.NET的 核心单元Borland.Delphi.System,了解Delphi的基于TObject的单根结构是如何映射到 CLR的FCL基于System.Object的单根结构上,并看看几个我们熟悉的TObject方法的实现, 了解Delphi和Delphi.NET在类的内存布局上的不同。 |
相关文章推荐
- Delphi.NET 内部实现分析(5)
- Delphi.NET 内部实现分析(4)
- Delphi.NET 内部实现分析(2)
- Delphi.NET 内部实现分析(2)
- Delphi.NET 内部实现分析(1)
- Delphi.NET 内部实现分析(3.3)
- Delphi.NET 内部实现分析(3.2)
- Delphi.NET 内部实现分析(3.4)
- Delphi.NET 内部实现分析(3.1)
- ASP.NET ViewState 实现分析(转贴)
- 32位图像处理库 delphi简单实现(转贴)
- Android 学习笔记之WebService实现远程调用+内部原理分析...
- [Asp.net 5] DependencyInjection项目代码分析4-微软的实现(5)(IEnumerable<>补充)
- 源码分析五(HashSet的内部实现)
- BUG_ON内部实现分析
- 转贴一篇很不错的有关ASP.NET Session的分析文章
- 应用框架的设计与实现——.NET平台(8.3 源码分析)
- (转载)ASP.NET 2.0客户端回调的实现分析 (二)
- 动态创建ASP.NET控件并保持其状态分析及实现
- 利用Anthem.net 实现前台javascript调用服务器端c#函数 及流程分析