网站导航免费论文 原创论文 论文搜索 原创论文 网学软件 学术大家 资料中心 会员中心 问题解答 原创论文 论文素材 设计下载 最新论文 下载排行 论文上传 在线投稿 联系我们
返回网学首页
网学联系
最新论文 推荐专题 热门论文 素材专题
当前位置: 网学 > 编程文档 > DELPHI > 正文
苛评VCL: 穿不透的类型
来源:Http://myeducs.cn 联系QQ:点击这里给我发消息 作者: 用户投稿 来源: 网络 发布时间: 12/10/12
下载{$ArticleTitle}原创论文样式

虽然遭遇到很多人的批评,但还是最终坚持下来。在这个系列中,主要是针对平时使用VCL的过程中,感觉Delphi没有处理好的地方。偶尔能提出一些自己的看法,权当谈资。更重要地是,我们可以借此学习到一些思想。

Delphi比起其他语言,有一个非常明显的特点,那就是类引用。典型的声明就是:

TComponentClass = class of TComponent;

可不要小看这个简单的声明,他可以让你直接访问到类的VMT。在李维先生的《Inside VCL》中谈到Delphi.NET的时候,也对此有特别的说明。对象和对象的差异,从一定意义上讲,就在于其所指向的VMT的不一样。

在VCL中,每个类的VMT都有自己的地址空间。于是VCL在判断两个类类型是否一致的时候,就是简单使用地址相等的方式。这里面最常用的就是Is操作符的实现了。遍历所有父类型,判断是否一致。

与VMT类似的,Delphi中的一些基本类型也是有自己的类型地址空间。这些类型的保存如果在C#中,你要说是类型反射。但在Delphi中,你更可以直接说成是为了实现published属性的类型检查。他们的类型检查也同样是使用地址空间来判断的。比如,判断一个属性是否为Boolean。你可以在TypInfo单元中找到相对应的实现代码。

我在实现一个TObjectGrid的时候,使用了RTTI信息来获取对象中属性的值。有一个需求是,判断某一个格子Cell所对应的属性是否为Boolean,如果是的话,使用CheckBox模式进行编辑。最初的实现代码是这样的:

if GetTypeData(PropInfo^.PropType^)^.BaseType^ = TypeInfo(Boolean) then

这段代码一直执行得很正常,直到有一天,我们的业务数据对象是从Dll返回。这个判断一下子实效了!

能够理解这个问题的人,应该能看出来,这是由于这个类型判断是使用地址空间引起的。Exe和Dll里有着自己独立的类型地址空间。当Dll加载到Exe中时,Dll中的类型地址空间经过重定位,因此Dll中的Boolean类型地址,和Exe中的类型地址不在时一个地址空间。我后来不得以,使用了名称的方式来判断类型是否一致。

如果你在Dll的接口中定义了TStrings类型的属性,那么在Exe中使用了TStrings类的Assign功能时会发生以外。这是因为TStrings实现Assign功能的时候,有这样一个判断:

if Source is TStrings then

经过上面的讲解,这段代码的判断显然返回False,那么其下面的赋值操作必然不会被执行。当然了,说到Is,应该能够想到,As操作符也会有类似的表现。因为As调用Is判断啊。

我上面讲了半天,其实就是说Exe和Dll之间的同一个类型不能够完全等同看待。特别是在接口之间传递的时候。当然了,我们可以说约定好,类型传递,不允许使用非基本类型。但是传递基础类的诱惑确实不小,这样,就少了很多处理了。

不过,正如LSuper大侠曾经提到的,在Delphi的Bpl之中就没有这个问题,因为他们的类型都是共享的。

应该说,针对VCL中的这个弱点,好的设计并不容易寻找。.NET中的Dll,已经实现了类型共享,这个Delphi的Bpl思想一致。想起来,应该是Dll的规范早于面向对象语言流行的原因。在早先的Dll定义中,并没有考虑复杂类型的接口传递。因此Delphi在上面实现会遇到很多问题。最大的就是语言和版本的问题。

  1. 不同的语言实现的Dll,如何保障类型相通?
  2. 不同版本的VCL类型,如何做到一致?

解决了这两个问题,类型就可以自由穿过应用程序边界了。我并不是希望Delphi重新设计这个缺陷。不过,可惜的是,Delphi并没有将自己的Bpl推广开来。就如.NET修改了Dll的规范一样。如果Delphi的Bpl也直接变成Dll,呵呵,还不知道结果会是什么样呢。

评论

#   wr960204 发表于2007-02-08 09:18:21  IP: 61.235.75.*
BPL本来就是DLL啊。
楼主一定没有用过早期版本的Delphi。早期版本的Delphi包的扩展名不是BPL而就是DLL。后来为了和标准通用的DLL区分,才改名叫BPL的。
只可惜BPL不能通用。只能在Borland的开发工具上使用。就像VC的扩展DLL一样,只能在VC中使用。
。NET的DLL也和BPL类似,虽然导出了类型之类东西。但也只能在。NET中使用。
楼主说的问题不过通用和特化的关系而已。和生物进化一样,特化的种类往往更能适应某种特定的环境,但禁不起环境的变化。非特化种类对任何环境都适应性差一点,但是却是进化的主力。
#
  • 上一篇资讯: 苛评VCL: Amingoo的留言
  • 下一篇资讯: 苛评VCL: 孤独的Application
  • 网学推荐

    免费论文

    原创论文

    浏览:
    设为首页 | 加入收藏 | 论文首页 | 论文专题 | 设计下载 | 网学软件 | 论文模板 | 论文资源 | 程序设计 | 关于网学 | 站内搜索 | 网学留言 | 友情链接 | 资料中心
    版权所有 QQ:3710167 邮箱:3710167@qq.com 网学网 [Myeducs.cn] 您电脑的分辨率是 像素
    Copyright 2008-2015 myeducs.Cn www.myeducs.Cn All Rights Reserved
    湘ICP备09003080号