关于反射的用途是『降低模块间的耦合度』这个倒未必尽然

单就delphi来说,从实现上看,它的所谓反射是基于RTTI,而RTTI的出现按照官方的说法是为了实现RAD中窗体文件DFM的持久化而产生的,其实也不是针对DFM文件或TForm啦,由于TPersistent在声明的时候加上了{$M+},所以从TPersistent派生的对象都在编译的时候添加了RTTI,而在TComponent中又增加了对TReader和TWriter支持,说的准确一点、时髦一点RTTI是为了实现对象的持久化和反持久化,在Delphi3之后加入了接口,从而将COM引入,而在delphi6以后又加入了对接口的RTTI的支持,从而将SOAP也引入到了delphi之中,从这两个重大特性的加入上看到,除了Delphi对接口支持的越来越丰富,还有一点很重要的是Delphi很早就支持了远程方法调用RPC,对于RPC的支持并不是简单的对传输协议的支持,而是要在对象定义、编译层面对其实现的支持。尽管COM的RPC与SOAP的RPC在表象上是有所不同的,但我们其实可以断定,在Delphi6之后已经就可以对对象的方法动态调用了。事实上也确实如此,一切奥秘尽包含在TypInfo,IntfInfo,ObjAuto,Invoker这些单元之中,只可惜在Help中并没有体现。我记得李维发过这样一句叹息,说其实在Borland实验室中十年前就有很多天才很多很Cool的想法但是得不到老板的支持,最后只得痛惜离开Borland。我在翻看VCL代码的时候,相信这确实是真的,现在很多在.NET或Java上很时髦的特性,有多少是Delphi在语言层面上是不支持的呢,我们忽略了Delphi是因为它们还没有来得及被Borland的工程师推向前台、还没来得及将其做成框架发布出来,而这些工程师就被赶跑了。

  可能是误会了反射的意思,这里并不是指对另外单元中声明的引用,而是指在运行时可以获得代码的特性以及在运行时可以改变它的行为。这样说可能抽象一点,说的稍微形象一点,一般编译型语言中,程序中所有定义的变量和函数,它们是否被使用、如何被使用,都是要在编码的时候设定好全部的执行逻辑的,而运行时只是遵循其中一条或几条执行路径执行的,而所谓的反射就是要能够在运行时通过一个外部的控制来决定程序内部的执行行为,也就是说从逻辑上看,程序不再是一个闭包的逻辑系统,而可以依赖于外部的注入。简单的说程序的运行时结构是由许多代码段、堆和栈这三种内存块组成,而所谓的执行就是指内部逻辑可以访问到代码段中的所有定义,将函数代码放在栈上展开执行,在堆中间分配所需空间以及一些其他的诸如IO访问等行为的集合。所以,如果要实现外部的控制注入,即反射,至少需要满足能够访问类似代码段上数据而获得变量和函数定义的部分,其次还要能够控制函数在栈上展开执行。

Delphi这种基于RTTI信息而实现的反射和Java、.Net有显著的不同。由于Java、.Net是先将程序编译成bytecode或CIL,在将中间代码让VM来执行,所以在这一类语言上实现反射的基本方式是获得bytecode和CIL,这部分内容就类似于代码段上的信息,然后外部注入的逻辑被重新编译生成新的中间代码后再让VM执行,从而产生新的行为。在这种机制下,非但可以实现反射,而且还可以对中间代码实行反编译而获得原始代码。而Delphi对反射的实现和Java以及.Net有本质的不同,它将对象的字段和函数的信息编译进RTTI,在编码的时候将对象注册进一个全局的列表中,运行时通过访问该列表而获得所需的对象,再从对象的RTTI中获得字段和函数的信息,同时提供出一种可以在运行时执行对象方法的函数,也不需要再编译,于是就间接的实现了反射机制。但是我们也应该注意到Delphi的反射和Java相比,首先是并不能反射到所有的变量和函数,例如全局的函数,静态变量就不会获得,其次由于不存在中间代码,也不存在反编译的问题,当然,这些都不是重点。其实这些东西在Delphi6\7的时候就已经有了,因为要支持SOAP,在SOAP标准中有一个SOAP的RPC表示,也就是说SOAP在调用远程对象方法的时候,也就是通过字符串来驱动的,所以不但有对象的RTTI,也可以在声明接口的 时候添加{$M+}来编译进接口的RTTI,从而对接口方法也可以使用字符串来驱动。又因为最初的设计是针对SOAP的,所以在ObjAuto单元中ObjectInvoke方法不支持对象类型和指针类型,毕竟SOAP在远程调用方法时传物理地址是没有意义的,当然,Variant也是不支持对象类型的。

delphi 反射(原理)的更多相关文章

  1. Delphi反射

    最近在写一个框架,需要用到反射,与C# java这些原生支持反射的语言不同,delphi对反射的支持相对要弱一些,但也够用了,其实C#的大部分的思想还是从 delphi而来,毕竟都是安德鲁斯的杰作. ...

  2. Lua刚開始学习的人(一)--Lua 简单教学

    近期因为工作原因.临时木有<Oracle起步学习>续集.领导知道学习下Lua脚本语言.看了一周了.趁热打铁,留下点实用的东西吧. 本系列会主要针对宿主语言为 Delphi,原理都是一样的, ...

  3. Django 的 cbv

    Django 的 cbv 正如我们了解到的,Django 写视图函数有两种写法:cbv 和 fbv.cbv 提倡使用类来写,fbv 使用函数来 写.当然为了代码的重复行,官方更推荐使用 cbv. 写 ...

  4. Shaderlab-10chapter-立方体纹理、玻璃效果

    10.1.1天空盒子 window - Lighting - skyMaterial 创建mat,shader选自带的6 side shader 确保相机选skybox 如果某个相机需要覆盖,添加sk ...

  5. IoC原理-使用反射/Emit来实现一个最简单的IoC容器

    从Unity到Spring.Net,到Ninject,几年来陆陆续续用过几个IoC框架.虽然会用,但也没有一直仔细的研究过IoC实现的过程.最近花了点时间,下了Ninject的源码,研究了一番,颇有收 ...

  6. Java反射机制及IoC原理

    一. 反射机制概念 主要是指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义.在java中,只要给定类的名字, 那么就可以通 ...

  7. Android反射机制实现与原理

    本文介绍Android反射机制实现与原理,在介绍之前,要和Java进行比较,所以先看下Java中的反射相关知识: 一.反射的概念及在Java中的类反射 反射主要是指程序可以访问.检测和修改它本身状态或 ...

  8. JAVA的反射机制原理

    http://www.cnblogs.com/hongxinlaoking/p/4684652.html 一  反射机制的概念: 指在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于 ...

  9. 【JAVA - 基础】之反射的原理与应用

    一.反射简介 反射机制指的是程序在运行时能够获取自身的信息.在JAVA中,只要给定类的名字,那么就可以通过反射机制来获取类的所有信息. 1.反射的应用 JDBC编程中的:Class.forName(& ...

随机推荐

  1. 致vi老大 2011.1

    文/安然 亲爱的,你即将离去 飞机起飞的一刻, 请珍藏起我们2010的回忆 桃源仙谷,曾留下我们踏青的足迹 难忘,石头上小憩 小北门外,我们在大排档里尽情欢喜 见证,杯盘狼藉 饺子店,是冬日里四面八方 ...

  2. 洛古 P1373 小a和uim之大逃离

    P1373 小a和uim之大逃离 题目提供者lzn 标签 动态规划 洛谷原创 难度 提高+/省选- 题目背景 小a和uim来到雨林中探险.突然一阵北风吹来,一片乌云从北部天边急涌过来,还伴着一道道闪电 ...

  3. Poj 2993 Emag eht htiw Em Pleh

    1.Link: http://poj.org/problem?id=2993 2.Content: Emag eht htiw Em Pleh Time Limit: 1000MS   Memory ...

  4. 关于apache Alias斜杠/的实验

    1.Alias /icons/ "D:/wamp/bin/apache/Apache2.2.17/icons/" 访问http://localhost/icons/正常,访问htt ...

  5. 压力测试 tpcc-mysql

    TPCC-MYSQL是由percona发布一个用来测试数据库的压力工具,模拟一个电商的业务, 主要的业务有新增订单,库存查询,发货,支付等模块的测试 1.下载 2.安装 1.解压   cd scr ; ...

  6. zhuan: ubuntu 安装 apache2

    安装 用  sudo apt-get install apache2 sudo /etc/init.d/apache2 restart 如果发现错误: 以下from:http://cache.baid ...

  7. ubuntu12.04 server + apache2 + wsgi + django1.6 部署

    最近在学Python和Django,想自己部署一个服务器试试 环境:ubuntu12.04 server | apache2 | django1.6 | python2.7 | mod_wsgi 在网 ...

  8. Wpf 简单制作自己的窗体样式(2)

    上一篇blog讲了制作简单的样式的窗体,对于一个传统的窗体,不仅仅可以拖动,和关闭操作.还具有最大化.最小化.隐藏,以及改变窗体的大小等.这篇blog就是对上篇的补充,完善窗体的改变大小和最大化最小化 ...

  9. hdu 4622 Reincarnation 字符串hash 模板题

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4622 题意:给定一个长度不超过2000的字符串,之后有不超过1e5次的区间查询,输出每次查询区间中不同 ...

  10. 分享自lordinloft 《[转载]COMPILE_OPT 的用法介绍》

    来源:http://blog.sina.com.cn/s/blog_63180b75010117oj.html#bsh-73-372143085