Delphi2010的RTTI增强

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;

 

 

 

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Delphi的运行时类型信息(RTTI)是在程序编译后生成的,它能够提供程序中各种对象的类型和成员信息。而Borland Package Library(BPL)是一种库文件格式,可以将Delphi代码编译成二进制形式,并且可以在运行时被动态加载。 要使用DelphiRTTI加载BPL文件,首先需要确保BPL文件已被正确编译生成。在Delphi开发环境中,可以通过编译项目生成BPL文件,确保在项目选项中的“生成”部分选择“包装编译”。 一旦BPL文件生成后,可以在Delphi代码中使用RTTI来加载它。在代码中,需要首先将BPL文件加载到内存中,可以使用LoadPackage函数来实现。LoadPackage函数接受BPL文件的完整路径作为参数,并返回一个HMODULE类型的句柄。 使用RTTI加载BPL文件的步骤如下: 1. 使用LoadPackage函数将BPL文件加载到内存中,并获取返回的句柄。 2. 使用GetModuleSymbols函数获取BPL文件中导出的符号列表。 3. 使用GetAddress函数获取需要使用的符号的地址。 4. 将获取到的地址转换成需要的类型,并使用该类型的功能。 使用RTTI加载BPL文件可以实现动态加载和调用其他模块中的函数、过程和类等功能。这使得开发者能够通过加载BPL文件来扩展程序的功能,提高了程序的灵活性和可扩展性。 需要注意的是,在使用RTTI加载BPL文件时,要确保加载的BPL文件与应用程序的目标平台、编译器版本等兼容,否则可能会引发不可预料的错误。另外,加载过多的BPL文件也可能导致程序性能下降,因此在设计时应考虑加载BPL文件的数量和大小。同时,加载BPL文件也可能存在安全风险,因此要谨慎选择加载的BPL文件来源。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值