Delphi2010的RTTI增强
2015-12-10 22:00
288 查看
Delphi编译的文件体积增大了很多.很大一部分原因是因为Delphi2010默认提供了全信息的RTTI.
每一个数据类型都有全部运行时信息.例如可以在运行时获得结构体的成员以及成员类型等.
这个功能带来的方便就是我们可以写很多通用的序列化方法.也可以做一些类似OR的东西.
相反这个功能带来的缺点就是文件体积将增大.
不过有一个解决方案.就是把运行时信息的编译开关关掉.但是编译期间连接的库在Lib目录下.这些DCU文件却都是带RTTI信息的.所以编译出来的内容也会是非常大的.就只有修改VCL源代码,全部关掉运行时信息的编译开关.然后把代码编译成DCU.放在LibNORTTI目录下.然后把Delphi项目的Lib路径指向这里.就可以达到去掉RTTI信息缩小可执行文件体积的目的了.不过貌似CodeGear应该在Delphi上加上一个选项,然后编译出两套VCL的DCU.根据不同选项连接不同目录下的DCU文件.我想CodeGear之所以没有这样做的原因应该是怕影响编译出来程序的一致性吧.
好了我们初步探索一下增强的RTTI吧.说起来很简单.
第一步uses RTTI;
然后照搬模式:
var
r : TRttiContext;
begin
r := TRttiContext.Creat();
写获取RTTI信息的代码
r.Free;
end;
TRttiContext的方法
GetTypes是获取系统内全部类型的类型信息数组.返回值类型是TArray<TRttiType>.(用到了从Delphi2009以来增加的泛型)
FindType是按名字找查找类型信息.
GetPackages是返回运行时包
GetType有两个重载方法.
function GetType(ATypeInfo: Pointer): TRttiType; overload;可以返回任何指定类型的类型嘻嘻
function GetType(AClass: TClass): TRttiType; overload;仅仅对Class有效.
下面就举个例子:
type
TTestRecord = record
a:string;
b:Integer;
c:Double;
end;
TTestClass = class
private
a:string;
b:Integer;
c:Double;
end;
var
r : TRttiContext;
rt : TRttiType;
f : TRttiField;
begin
r := TRttiContext.Create();
rt := r.GetType(TTestClass);
for f in rt.GetFields() do
begin
OutputDebugString(PChar(Format('%s.%s:%s',[rt.Name, f.Name, f.FieldType.Name])));
end;
r.Free;
end;
在Delphi的EventLog中就可以看到TTestClass的成员,不关它是私有还是公有的.
结构体和其他类型则可以用function GetType(ATypeInfo: Pointer): TRttiType;这个方法,当然这个方法也可以处理Class类型
所区别就在于要加上TypeInfo操作符取回类型信息指针.
var
r : TRttiContext;
rt : TRttiType;
f : TRttiField;
begin
r := TRttiContext.Create();
rt := r.GetType(TypeInfo(TTestClass));
for f in rt.GetFields() do
begin
OutputDebugString(PChar(Format('%s.%s:%s',[rt.Name, f.Name, f.FieldType.Name])));
end;
rt := r.GetType(TypeInfo(TTestRecord));
for f in rt.GetFields() do
begin
OutputDebugString(PChar(Format('%s.%s:%s',[rt.Name, f.Name, f.FieldType.Name])));
end;
r.Free;
end;
http://blog.csdn.net/wr960204/article/details/4584503
每一个数据类型都有全部运行时信息.例如可以在运行时获得结构体的成员以及成员类型等.
这个功能带来的方便就是我们可以写很多通用的序列化方法.也可以做一些类似OR的东西.
相反这个功能带来的缺点就是文件体积将增大.
不过有一个解决方案.就是把运行时信息的编译开关关掉.但是编译期间连接的库在Lib目录下.这些DCU文件却都是带RTTI信息的.所以编译出来的内容也会是非常大的.就只有修改VCL源代码,全部关掉运行时信息的编译开关.然后把代码编译成DCU.放在LibNORTTI目录下.然后把Delphi项目的Lib路径指向这里.就可以达到去掉RTTI信息缩小可执行文件体积的目的了.不过貌似CodeGear应该在Delphi上加上一个选项,然后编译出两套VCL的DCU.根据不同选项连接不同目录下的DCU文件.我想CodeGear之所以没有这样做的原因应该是怕影响编译出来程序的一致性吧.
好了我们初步探索一下增强的RTTI吧.说起来很简单.
第一步uses RTTI;
然后照搬模式:
var
r : TRttiContext;
begin
r := TRttiContext.Creat();
写获取RTTI信息的代码
r.Free;
end;
TRttiContext的方法
GetTypes是获取系统内全部类型的类型信息数组.返回值类型是TArray<TRttiType>.(用到了从Delphi2009以来增加的泛型)
FindType是按名字找查找类型信息.
GetPackages是返回运行时包
GetType有两个重载方法.
function GetType(ATypeInfo: Pointer): TRttiType; overload;可以返回任何指定类型的类型嘻嘻
function GetType(AClass: TClass): TRttiType; overload;仅仅对Class有效.
下面就举个例子:
type
TTestRecord = record
a:string;
b:Integer;
c:Double;
end;
TTestClass = class
private
a:string;
b:Integer;
c:Double;
end;
var
r : TRttiContext;
rt : TRttiType;
f : TRttiField;
begin
r := TRttiContext.Create();
rt := r.GetType(TTestClass);
for f in rt.GetFields() do
begin
OutputDebugString(PChar(Format('%s.%s:%s',[rt.Name, f.Name, f.FieldType.Name])));
end;
r.Free;
end;
在Delphi的EventLog中就可以看到TTestClass的成员,不关它是私有还是公有的.
结构体和其他类型则可以用function GetType(ATypeInfo: Pointer): TRttiType;这个方法,当然这个方法也可以处理Class类型
所区别就在于要加上TypeInfo操作符取回类型信息指针.
var
r : TRttiContext;
rt : TRttiType;
f : TRttiField;
begin
r := TRttiContext.Create();
rt := r.GetType(TypeInfo(TTestClass));
for f in rt.GetFields() do
begin
OutputDebugString(PChar(Format('%s.%s:%s',[rt.Name, f.Name, f.FieldType.Name])));
end;
rt := r.GetType(TypeInfo(TTestRecord));
for f in rt.GetFields() do
begin
OutputDebugString(PChar(Format('%s.%s:%s',[rt.Name, f.Name, f.FieldType.Name])));
end;
r.Free;
end;
http://blog.csdn.net/wr960204/article/details/4584503
相关文章推荐
- DelphiXe5中的双向绑定(使用使用TBindScope和TBindExpression,并覆盖AfterConstruction函数)
- delphi 调用c/c++函数dll的坑
- Delphi IOS 上架
- Delphi XE7 发布时间
- The CompilerVersion constant identifies the internal version number of the Delphi compiler.
- 【Delphi内联汇编学习1】Delphi与汇编
- 在delphi的exe文件中嵌入另外一个exe文件
- DevExpress 控件中设置分隔符
- 关于delphi下clientsocket的重复连接问题
- Delphi iOS Gesture 事件触发的探索
- Delphi 3种获取网页源代码实例。
- delphi7 下的Excel导出
- Delphi异常处理机制
- Delphi 快速检测是否联网
- 用C#实现Delphi的TStringList类
- delphi 手电筒
- Delphi 函数指针(三大好处:灵活,委托的本质,回调机制),还可把函数指针当参数传入
- Delphi获取本机的MAC地址
- delphi读取和写入文件-richedit控件
- Delphi下POS机