Delphi.NET 内部实现分析(3.1)
来源:百度文库 编辑:神马文学网 时间:2024/04/28 01:04:03
2. Borland.Delphi.System
2.1. 简介
与传统Delphi程序编译时默认包含System单元类似,Delphi.NET程序编译时默认保护了
Borland.Delphi.System单元,而此单元中集中了诸多基础之基础的类和函数的定义、实现。
与Delphi不同的是,目前Delphi.NET的预览版中,Borland.Delphi.System还只是包含了
相对基本的功能,如TObject类及其相关辅助函数、以及一些基础的函数,特别是很多带下划线
前缀的函数,根本就是由编译器一级固化支持,如标准输入输出函数中的WriteLn以及字符串处理函数等等。
下面我们来一点点分析这个最基础的单元:Borland.Delphi.System。
2.2. 元类
语言的发展历程,就是对问题域的抽象层面的逐渐提升的过程。在Delphi、C#以及Java这些
现代语言中,一个很重要的特性就是对RTTI 运行时类型信息的支持,而且支持将越来越完善。
Delphi在这方面一个实例就是元类的概念的运用,用以对类的信息进一步抽象。
关于元类的概念以及使用,已经有大量书籍论述过,这里不再多说,让我们来看看实现。
在传统Delphi的Object Pascal语言中,元类在实现上实际上就是一张VMT(Virtual Method Table
虚方法表),在System单元的定义中可以详细看到其含义
//-----------------------------------------System.pas--
{ Virtual method table entries }
vmtSelfPtr = -76;
vmtIntfTable = -72;
vmtAutoTable = -68;
vmtInitTable = -64;
vmtTypeInfo = -60;
vmtFieldTable = -56;
vmtMethodTable = -52;
vmtDynamicTable = -48;
vmtClassName = -44;
vmtInstanceSize = -40;
vmtParent = -36;
vmtSafeCallException = -32 deprecated; // don‘t use these constants.
vmtAfterConstruction = -28 deprecated; // use VMTOFFSET in asm code instead
vmtBeforeDestruction = -24 deprecated;
vmtDispatch = -20 deprecated;
vmtDefaultHandler = -16 deprecated;
vmtNewInstance = -12 deprecated;
vmtFreeInstance = -8 deprecated;
vmtDestroy = -4 deprecated;
//-----------------------------------------System.pas--
普通对象的第一个双字就是指向其类的VMT的指针,以此将对象、类和元类关联起来。
这个VMT表是Delphi中类的核心所在,通过它可以在运行时获取类的绝大部分信息。
例如在VMT中有一个vmtSelfPtr指针又回指到VMT表头,我们可以利用这个特性判断一个
指针指向的是否是有效的对象或类。JCL项目中有代码如下
//-----------------------------------------JclSysUtils.pas--
function IsClass(Address: Pointer): Boolean; assembler;
asm
CMP Address, Address.vmtSelfPtr
JNZ @False
MOV Result, True
JMP @Exit
@False:
MOV Result, False
@Exit:
end;
function IsObject(Address: Pointer): Boolean; assembler;
asm
// or IsClass(Pointer(Address^));
MOV EAX, [Address]
CMP EAX, EAX.vmtSelfPtr
JNZ @False
MOV Result, True
JMP @Exit
@False:
MOV Result, False
@Exit:
end;
//-----------------------------------------JclSysUtils.pas--
通过VMT中其它的域可以完成更多奇妙的功能,如D6开始对SOAP支持在实现上,
就是通过VMT动态查表完成SOAP函数调用到Delphi接口的函数调用转发的。
而在Delphi.NET中,因为Borland无法控制类在内存中的组织方式,因而只能
通过前面提到的class helper的补丁方式,让CLR的BCL的System.Object使用上
看起来象TObject。这样的确能够在很大程度上提供源代码级兼容性,但对JclSysUtils
这样的Hacker代码就无能为力了 :)
2.1. 简介
与传统Delphi程序编译时默认包含System单元类似,Delphi.NET程序编译时默认保护了
Borland.Delphi.System单元,而此单元中集中了诸多基础之基础的类和函数的定义、实现。
与Delphi不同的是,目前Delphi.NET的预览版中,Borland.Delphi.System还只是包含了
相对基本的功能,如TObject类及其相关辅助函数、以及一些基础的函数,特别是很多带下划线
前缀的函数,根本就是由编译器一级固化支持,如标准输入输出函数中的WriteLn以及字符串处理函数等等。
下面我们来一点点分析这个最基础的单元:Borland.Delphi.System。
2.2. 元类
语言的发展历程,就是对问题域的抽象层面的逐渐提升的过程。在Delphi、C#以及Java这些
现代语言中,一个很重要的特性就是对RTTI 运行时类型信息的支持,而且支持将越来越完善。
Delphi在这方面一个实例就是元类的概念的运用,用以对类的信息进一步抽象。
关于元类的概念以及使用,已经有大量书籍论述过,这里不再多说,让我们来看看实现。
在传统Delphi的Object Pascal语言中,元类在实现上实际上就是一张VMT(Virtual Method Table
虚方法表),在System单元的定义中可以详细看到其含义
//-----------------------------------------System.pas--
{ Virtual method table entries }
vmtSelfPtr = -76;
vmtIntfTable = -72;
vmtAutoTable = -68;
vmtInitTable = -64;
vmtTypeInfo = -60;
vmtFieldTable = -56;
vmtMethodTable = -52;
vmtDynamicTable = -48;
vmtClassName = -44;
vmtInstanceSize = -40;
vmtParent = -36;
vmtSafeCallException = -32 deprecated; // don‘t use these constants.
vmtAfterConstruction = -28 deprecated; // use VMTOFFSET in asm code instead
vmtBeforeDestruction = -24 deprecated;
vmtDispatch = -20 deprecated;
vmtDefaultHandler = -16 deprecated;
vmtNewInstance = -12 deprecated;
vmtFreeInstance = -8 deprecated;
vmtDestroy = -4 deprecated;
//-----------------------------------------System.pas--
普通对象的第一个双字就是指向其类的VMT的指针,以此将对象、类和元类关联起来。
这个VMT表是Delphi中类的核心所在,通过它可以在运行时获取类的绝大部分信息。
例如在VMT中有一个vmtSelfPtr指针又回指到VMT表头,我们可以利用这个特性判断一个
指针指向的是否是有效的对象或类。JCL项目中有代码如下
//-----------------------------------------JclSysUtils.pas--
function IsClass(Address: Pointer): Boolean; assembler;
asm
CMP Address, Address.vmtSelfPtr
JNZ @False
MOV Result, True
JMP @Exit
@False:
MOV Result, False
@Exit:
end;
function IsObject(Address: Pointer): Boolean; assembler;
asm
// or IsClass(Pointer(Address^));
MOV EAX, [Address]
CMP EAX, EAX.vmtSelfPtr
JNZ @False
MOV Result, True
JMP @Exit
@False:
MOV Result, False
@Exit:
end;
//-----------------------------------------JclSysUtils.pas--
通过VMT中其它的域可以完成更多奇妙的功能,如D6开始对SOAP支持在实现上,
就是通过VMT动态查表完成SOAP函数调用到Delphi接口的函数调用转发的。
而在Delphi.NET中,因为Borland无法控制类在内存中的组织方式,因而只能
通过前面提到的class helper的补丁方式,让CLR的BCL的System.Object使用上
看起来象TObject。这样的确能够在很大程度上提供源代码级兼容性,但对JclSysUtils
这样的Hacker代码就无能为力了 :)
Delphi.NET 内部实现分析(3.1)
Delphi.NET 内部实现分析(1)
Delphi.NET 内部实现分析(2)
Delphi.NET 内部实现分析(3.2)
Delphi.NET 内部实现分析(3.3)
Delphi.NET 内部实现分析(3.4)
Delphi.NET 内部实现分析(4)
Delphi.NET 内部实现分析(5)
Delphi.NET 内部实现分析(5)
Delphi.NET 内部实现分析(4)
Delphi.NET 内部实现分析(3.4)
PAM 的应用开发和内部实现源码分析
Delphi中PING的实现
Delphi和Java实现webservice
用DELPHI实现为NT添加用户
Delphi中PING的实现ewe
Delphi中PING的实现a
Delphi屏幕截图技术实现2
Delphi屏幕截图技术实现d
使用.NET实现断点续传
在Delphi中实现VFP6的查询速度 - Delphi - 文档中心 - 源码天空
浅析多层结构及其在Delphi中的实现<一>
Delphi中不使用第三方控件实现XP风格
DELPHI的RTTI实现数据集的简单对象化