Delphi 8 for .net 第一时间 之 分析篇

原创 2003年12月26日 11:12:00

Delphi 8 for .net 第一时间 之 分析篇<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 

 

_________________________________________________________________________

   本文章只是作者这两天试用D8并对VCL.net源码稍微查看了一下,作出的一些分

   析判断,时间水平有限请见谅 cocoboy79#163.com  qq:364941)

 

   下文中:D7代表基于Win32版本的Delphi,D8代表Delphi 8 for .net 

__________________________________________________________________________

 

  一直在使用Delphi编程,也一直关注.net技术。又是时代变化的时候了,VCl.net对于我们来说是一个完美的.net解决方案么?还是用于过度的桥梁?,如果你和我一样使用Delphi,那么我们是时候思考一下如何利用现有的Delphi技能更快的搭上.net快车。下面是这两天稍使用了一下Delphi8而总结一点东西,共同分享,共同思考。

 

TList:
    我们都知道TList实际上是一个功能强大的地址列表,这种数据结构非常有用。对于一个在D7中的TList的实例来说,这个地址列表中每一个项目(Item)是一个Pointer类型,你可以像下面程序一样,把对象变量或是一个值类型的指针(比如一个指向Record型的指针变量)存放到里面,在需要时取出来,并可以进行运行期类型转换。
var
  myList:TList;
  myLab:TLabel;
  i:integer;
begin
   myList:=TList.Create;
   for i:=0 to 10 do
   begin
     myLab:=TLabel.Create(self);
     myLab.Parent:=Self;
     myLab.Caption:='这是第 '+IntToStr(i)+' 个';
     myList.Add(myLab);
   end;
   for i:=0 to myList.Count-1 do
   begin
     ShowMessage( TLabel(myList.Items[i]).Caption );
   end;
end;

   在.net中你也会找到与之相像的一个东西,它就是.net中的ArrayList(System.Collections.ArrayList),我在大概看了一下发现ArrayList可以说是
TList的一个增强,唯一不足的就是它不开放源码,我们没办法看到是如何实现的。而且我们会发现D8中的TList的实现也与ArrayList有关。 

  让我们来稍微看一下D7与D8中TList的源码的声明吧,(整个类声明请查看D7,8的TList源码,对于不开源的ArrayList就无能为力了)

 

这是D7中的TList的一些声明
FList: PPointerList;
property List: PPointerList read FList;
function Add(Item: Pointer): Integer;
function First: Pointer;
function Last: Pointer;

这是D8中的TList的一些声明
FList: System.Collections.ArrayList;
property List: System.Collections.ArrayList read FList;
function Add(Item: TObject): Integer;
function First: TObject;
function Last: TObject;

这是在D7是PpointerList的声明:
PPointerList = ^TPointerList;
TPointerList = array[0..MaxListSize - 1] of Pointer;
 
    看一下D7的TList,TList内部维护的Flist是一个PpointerList,实际上就是一个指向TpointerList的指针,(如最上面的程序,myList.Add(myLab)实际上就是往Flist中增加元素)TpointerList是一个静态的元素为无类型指针的数组。Pointer类型为无类型指针,这个在D7中的Pointer在D8的.net mangaged环境已经不能使用了,如果你在Vcl.net工程中声明一个Pointer变量,按f9会被告知: UnSafe pointer variables,parameters or consts only allowed in unsafe procedure 。所以上面D8的TList源码声明中的所有Pointer已经变成了Tobject,(注意这个TObject其实已经不是原先D7那个TObject了,它是:System.Object,这个等会再说。)。引用的一篇文章的一句话:Pointer -- There is a Pointer type, but in safe code Pointer is a reference to an object. You can't do pointer math on it.(
http://delphi.weblogs.com),在.net的managed环境中指针代表对象的引用。即然原先的Pointer已经不能用了,那么Flist:PpointerList也就不能成立,于是它在D8中被改成了FList: System.Collections.ArrayList,所有Pointer都成了Tobejct。那么ArrayList,请去看看.Net的MSDN,功能上完全可以充当一个指针数组,只不过它的元素由Pointer变成了Tobject类型。

   其实看完了想想上面这个问题也很简单,就是一个寻找替代品的问题,看看D8的TList各方法的源码基本都没有变。后来我又看了一个其它类的源码发现在VCL.net中有好多这种’替代情况’,当原先的Delphi语言元素在.net环境中不便于或不能使用时,总会有一个.net framework中的替代品。

 

TObject:


  打开D8中的 Borland.Delphi.System.pas只看一下上面几行
   type
  TObject = System.Object;
  TCustomAttribute = System.Attribute;
  Exception = System.Exception;
  TGUID = System.Guid;
   

  这与D7的TObject,Exception类的定义已经大不相同了,在D8中TObject就是.net的System.Object,另外那个Exception也一样。“.NET Framework 中的所有类均从 Object 派生,所以 Object 类中定义的每个方法可用于系统中的所有对象。派生类可以而且确实重写这些方法中的某些,其中包括:”-------来自MSDN,那么就很自然了,原先VCL的TObject的地位和作用与上面MSDN里对System.Object类描述一样,那VCL要移植到.net就必须照办,即TObject定义为System.Object,而对于子类来说,声明还是subclass=class(TObject) ,但实际上已经是System.Object了,底层处理完全由.net framework来进行。而且没有System.Object的源码我们也不知道它干了什么。

 

TComponent:

  新建一个VCL.net工程,然后在Form上放一个Tedit或是Tmemo按f9,你会发现在代码编辑器上面的uses里比以前多了一个System.ComponentModel,如下所示。

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, System.ComponentModel, Borland.Vcl.StdCtrls;
    这是为什么?也是很简单,打开Borland.Vcl.Classes.pas文件找到114行有如下声明:TComponent = System.ComponentModel.Component;好了。。和TObject一样我们现在的Tcomponet已经和原先那个完全不同了,只是具有相同的名字,而且你也不用操心Tcomponent怎么实现的了,因为System.ComponentModel.Component的源码是不公开的。类似的还有  TPersistent = System.MarshalByRefObject 等等。


  Windows.Pas

  我们看一下这个单元吧,里面有一些对Windows Api的直接声明和调用。打开Borland.Vcl.Windows.pas找到19871行,看看implementation下面的一些Api的
声明如下:

[DllImport(advapi32, CharSet = CharSet.Ansi, SetLastError = True, EntryPoint = 'AbortSystemShutdown')]

function AbortSystemShutdown; external;

  上面那个[Dll... ]学过点.net的都知道是Attribute,是一种新东东好像Java里也没这个,算是.net原创的了(具体怎么用在csdn文档区见过一系相关文章请找一下)对于[Dll Import ……….]看一下MSDN:“ DllImportAttribute 属性提供对从非托管 DLL 导出的函数进行调用所必需的信息。作为最低要求,必须提供包含入口点的 DLL 的名称。”也就是说在.net里要使用一个像Windows Api所在的DLL或是普通基于Win32的DLL这样的库时都要像这种格式先用Attribute声明,然后.net系统就会知道这是一个非安全代码组成的程序,于是像下图这样进行调用。我个人认为这种方法并不是‘纯.net的方法’,只是能够让程序运行而已,是一种兼容的方法。换言之VCL.net在某种程度上说是兼容运行于.net平台的,并不是.net原生方式,或者说在一定程度上是以Win32程序的托管方式运行,所以………(纯属个人想法)。请参考下图:

 

(以下图及注解摘自MSDN.net)

<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />

CSDN_Dev_Image_2003-12-252252270.jpg

“平台调用”调用非托管函数时,它将依次执行以下操作:

  1. 查找包含该函数的 DLL
  2. 将该 DLL 加载到内存中。
  3. 查找函数在内存中的地址并将其参数推到堆栈上,以封送所需的数据。 注意   只在第一次调用函数时,才会查找和加载 DLL 并查找函数在内存中的地址。
  4. 将控制权转移给非托管函数。

平台调用会向托管调用方引发由非托管函数生成的异常。

总结:
    这几天除了稍使用了一下Delphi8外,还到borland的以及一些vcl第3方供应商(devexpress.com)的newsgroup上看了一下,个人现在认为VCL.net(或者说Delphi for .net)能够让Delphi程序员比较省事的过度到.net平台进行开发。但这并不意味着我们就不用去学C#和.net framework,学这两样东西早晚的事,我看重要的还是学习.net framework。Microsoft现在把.net系统低层功能也用类库的方式实现,Microsoft下一代OS也是基于.net,到时像上面这种Windows Api调用能不能用还不得而知,估计就算能用也永远不是最好的办法了。所以个人估计Borland是不是在忙完了他的很长的产品线的更新换代以及发展像ECO这样高层技术后,是否考虑重新构造类库?D8中的BDP以及ECO算不是是新类库的冰山一角呢?还是Borland只是在局部做一些与Microsoft技术对应的东西,
比如BDP-ADO.NET ECO-object Space 。

个人看来可以利用VCL.net的便利把以前的可能用于.net的VCL程序移植成.net的。然后还是用Delphi Language就着MSDN.net来学习如何运用.net frameWork吧。不过VCL或VCL.net由于开放源码,并且后者有很多地方与.net frameWork相结合,所以对于学习来说是很宝贵的资料,应该可以学习很多设计思路。

                           by ithink79

                                                      2003-12-25

量化分析师的Python日记【第6天:数据处理的瑞士军刀pandas下篇

####第二篇:快速进阶 在上一篇中我们介绍了如何创建并访问pandas的Series和DataFrame类型的数据,本篇将介绍如何对pandas数据进行操作,掌握这些操...
  • youmengdaigu
  • youmengdaigu
  • 2015年11月08日 09:54
  • 2255

Spark修炼之道(高级篇)——Spark源码阅读:第四节 Stage划分

Stage划分在上一节中我们讲了 Spark Job的提交,在该讲中我们提到,当rdd触发action操作之后,会调用SparkContext的runJob方法,最后调用的DAGScheduler.h...
  • lovehuangjiaju
  • lovehuangjiaju
  • 2015年10月24日 23:48
  • 5271

Spark修炼之道(进阶篇)——Spark入门到精通:第一节 Spark 1.5.0集群搭建

作者:周志湖 网名:摇摆少年梦 微信号:zhouzhihubeyond本节主要内容 操作系统环境准备 Hadoop 2.4.1集群搭建 Spark 1.5.0 集群部署 注:在利用CentOS 6...
  • lovehuangjiaju
  • lovehuangjiaju
  • 2015年12月28日 21:36
  • 16731

.net 日期时间格式化

本文转载自:http://www.cnblogs.com/dongqi/archive/2009/04/01/1426827.html GridView中Dataformatstri...
  • luxin10
  • luxin10
  • 2011年11月21日 13:49
  • 343

QQ留言群发第一时间抢沙发

  • 2010年01月13日 13:25
  • 3.34MB
  • 下载

U盘监控大师 实时监控U盘,第一时间查杀U盘病毒!!

  • 2009年05月23日 16:39
  • 743KB
  • 下载

第一时间捕获段错误(segment fault)的详细信息

不使用gdb也能捕获段错误的详细信息,事实上,使用gdb是一件很麻烦的事情!第一,gdb功能太过强大,诊断个段错误真是大材小用,如果不会用还要学...其次,很多系统并没有安装这个工具。因此最好的办法就...
  • dog250
  • dog250
  • 2011年08月20日 10:18
  • 7663

Windows Docker第一时间揭秘

  • 2017年12月15日 20:52
  • 1.12MB
  • 下载

vvv第一时间得到新产品上市和优惠活动通知

  • 2009年04月17日 15:52
  • 256KB
  • 下载

广州传智播客.Net培训基础加强班 给你真正的技术

广州传智播客.Net培训基础加强班 给你真正的技术     很多初学编程的人总是对编程很恐惧,经常质疑自己“这么多东西我能学会吗?”,实际上编程就是“让计算机记住做事儿的步骤,然后由...
  • u010395024
  • u010395024
  • 2013年11月12日 15:07
  • 460
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Delphi 8 for .net 第一时间 之 分析篇
举报原因:
原因补充:

(最多只允许输入30个字)