zoukankan      html  css  js  c++  java
  • 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;
  • 相关阅读:
    (寒假练习 AcWing 870)约数个数(数论)
    (补题 CF 1271B) Blocks
    (补题 POJ-2228)Naptime(环状DP)
    实验 ·SQL语言综合练习
    (补题 水题 汇总)四川大学第二届SCUACM新生赛
    (补题 CF 455A)Boredom(DP)
    (补题 HDU 1176)免费馅饼(DP)
    deppin下使用vscode编写C++
    (补题 CF 355B) Vasya and Public Transport
    【数据结构】ACwing-41. 包含min函数的栈【单调栈】
  • 原文地址:https://www.cnblogs.com/del88/p/6364232.html
Copyright © 2011-2022 走看看