标签: rtti

发现具有多个继承级别的属性首次发布的类

使用Typinfo单元,可以轻松枚举属性,如以下代码段所示:

procedure TYRPropertiesMap.InitFrom(AClass: TClass; InheritLevel: Integer = 0);
var
  propInfo: PPropInfo;
  propCount: Integer;
  propList: PPropList;
  propType: PPTypeInfo;
  pm: TYRPropertyMap;
  classInfo: TClassInfo;
  ix: Integer;

begin
  ClearMap;

  propCount := GetPropList(PTypeInfo(AClass.ClassInfo), propList);
  for ix := 0 to propCount - 1 do
  begin
    propInfo := propList^[ix];
    propType := propInfo^.PropType;

    if propType^.Kind = tkMethod then
      Continue; // Skip methods
    { Need to get GetPropInheritenceIndex to work
    if GetPropInheritenceIndex(propInfo) > InheritLevel then
      Continue; // Dont include properties deeper than InheritLevel
    }
    pm := TYRPropertyMap.Create(propInfo.Name);
    FList.Add(pm);
  end; …
Run Code Online (Sandbox Code Playgroud)

delphi enumeration properties rtti

7
推荐指数
1
解决办法
639
查看次数

Rtti访问复杂数据结构中的字段和属性

正如在Rtti数据处理和Delphi 2010中的一致性中已经讨论的那样,通过使用一对TRttiField和实例指针访问成员,可以达到原始数据和rtti值之间的一致性.对于只有基本成员类型(例如整数或字符串)的简单类,这将非常容易.但是,如果我们有结构化的字段类型呢?

这是一个例子:

TIntArray = array [0..1] of Integer;

TPointArray = array [0..1] of Point;

TExampleClass = class
  private
    FPoint : TPoint;
    FAnotherClass : TAnotherClass;
    FIntArray : TIntArray;
    FPointArray : TPointArray;
  public  
    property Point : TPoint read FPoint write FPoint; 
    //.... and so on
end;
Run Code Online (Sandbox Code Playgroud)

为了方便成员访问,我想构建一个成员节点树,它提供了一个获取和设置值,获取属性,序列化/反序列化值等的接口.

TMemberNode = class
  private
    FMember : TRttiMember;
    FParent : TMemberNode;
    FInstance : Pointer;
  public
    property Value : TValue read GetValue write SetValue; //uses FInstance
end;
Run Code Online (Sandbox Code Playgroud)

所以最重要的是获取/设置值,这是通过使用TRttiField的GetValue和SetValue函数完成的 - 如前所述.

那么FPoint成员的实例是什么?假设Parent是TExample类的Node,其中实例是已知的,成员是一个字段,那么Instance将是:

FInstance := Pointer …
Run Code Online (Sandbox Code Playgroud)

delphi rtti delphi-2010

7
推荐指数
1
解决办法
6890
查看次数

Rtti不适用于用作类字段的泛型类型

我在使用rtti获取有关泛型类字段的信息时遇到了问题.经过一段时间的谷歌搜索后,我在QC中找到了一个描述该问题的条目.我的问题是,如果有人知道一个解决方法,或者这是否修复了Delphi XE2.以下是来自QC的重复该错误的源代码片段.

program Generics;

    {$APPTYPE CONSOLE}

    uses
       Generics.Collections, Rtti, SysUtils;

    type
       TIntList = TList<Integer>;

       TRecContainer = record
         FList: TIntList;
       end;

       TObjContainer = class
         FList: TIntList;
       end;

    var
       ctx: TRttiContext;
       f: TRttiField;

    begin
       ctx := TRttiContext.Create;
       try
         for f in ctx.GetType(TypeInfo(TRecContainer)).GetFields do
           if f.FieldType <> nil then
             writeln(f.FieldType.Name)
           else
             writeln('f.FieldType = nil');
         for f in ctx.GetType(TypeInfo(TObjContainer)).GetFields do
           if f.FieldType <> nil then
             writeln(f.FieldType.Name)
           else
             writeln('f.FieldType = nil');
       finally
         ctx.Free;
         readln;
       end;
    end.
Run Code Online (Sandbox Code Playgroud)

delphi rtti delphi-xe

7
推荐指数
1
解决办法
1381
查看次数

是否可以使用TypeKind = tkMethod为TRttiType创建TRttiMethod实例?

大家好:)这是我在stackoverflow的第一个问题:)

在Delphi XE2 RTTI中我们有TRttiMethod类,它具有CreateImplementation()动态创建过程或函数的功能,它具有相同的签名和与其正文相同的方法.

使用TRttiContext.getMethods()/ getMethod()我们可以获得类方法的集合 - TRttiMethod的集合.

文档说(http://docwiki.embarcadero.com/VCL/en/RTTI.TRttiMethod)不要直接创建TRTTiMethod,并使用getMethods()来获取其实例.

所以,如果我们有TRTTIMethod实例,我们可以动态创建具有相同签名的方法,并在以后调用它.

问题是..例如,我们有TNotifyEvent ... TRttiContext.getType(typeinfo(TNotifyEvent))返回TRttiType具有typekind =的实例对象tkMethod.我们知道TNotifyEvent的签名是对象的过程(sender:TObject);

有可能得到TRttiMethod这个吗?我想为事件动态创建eventHandler,TRttiMethod.CreateImplementation() 或者可能有另一种方法动态创建方法实现?

PS:想法是创建类似事件链的东西.在编译时,我们不知道事件类型/签名,因此我们可以使用泛型,如TEvenChain <TNotifyEvent>.Chain在已注册的事件处理程序上有集合,因为我们在编译时不知道处理程序类型,我们必须动态创建它,并且该处理程序只获取其参数并使用它们调用已注册的处理程序.

更新: 这里是一些代码(想法是创建事件处理程序链):

procedure TMainForm.FormCreate(Sender: TObject);
begin
    FEventChain := TNotifyChain.Create();
    FEventChain.AddHandler(event1);
    FEventChain.AddHandler(event2);   

    TestButton.OnClick := FEventChain.EventHandler;
end;
Run Code Online (Sandbox Code Playgroud)

Event1&event2(sender : TObject)形式的方法; 它不是一般示例(T在这种情况下是NotifyEvent/TChain <TNotifyEvent>) TEventChain.EventHandlerTNotifyEvent

TNotifyChain

TNotifyChain = class(TObject)
  strict private
    FEvent : TNotifyEvent;
    FItems : TList<TNotifyEvent>;

    FCtx : TRttiContext; …
Run Code Online (Sandbox Code Playgroud)

delphi rtti delphi-xe2

7
推荐指数
1
解决办法
1366
查看次数

可以在Delphi XE中使用"未使用"类

我在Delphi XE,Windows 7中工作.

在应用程序中,我想为我的用户启用不同的报告类型以供选择.为此,我有一个基本报告类和每个报告类型的子类(xml,csv,ppt等).

{Just an illustrating example}
TBaseReport = class
public
  constructor Create;
  procedure GenerateReport; virtual; abstract;
  class function ReportType: string; virtual; abstract;
end;

T*Report = class(TBaseReport);
//Etcetera.
Run Code Online (Sandbox Code Playgroud)

我想要做的是使用Rtti检测所有报告类并列出他们的ReportType.之后,我想使用Rtti创建所选报告类的实例并调用GenerateReport.总而言之,这并不难实现.

但是有一个主要的缺点:我从不硬编码使用降序类,因此代码不会包含在可执行文件中.

有没有一种不错的方法来强制链接器/编译器包含这些类?

一个(丑陋的)解决方法是在初始化部分模拟报告的使用,但我宁愿不这样做.更好的解决方案是使基类持久化并调用'RegisterClass(T*Report);' 在初始化部分.它有效,但我没有看到任何其他需要使它们持久化,所以再次,我宁愿不这样做.另一方面,也许这是唯一的方法吗?

提前致谢.

delphi rtti delphi-xe

7
推荐指数
2
解决办法
417
查看次数

type_info不是RTTI的一部分吗?

我曾问过一个问题C++ POD类型有RTTI吗?有人在评论中告诉我:

POD类型确实有type_info,但没有RTTI,这是可能的,因为type_info并不总是RTTI.

它似乎是正确的,因为我可以获得type_infoPOD(非多态)类型.

但是当我编译这个简单的程序时:

#include <iostream>

struct X
{
    int a;
};

int main()
{
    using namespace std;

    std::cout << typeid(X) << std::endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

-fno-rtti海湾合作委员会的旗帜:

$ g++ -fno-rtti main.cpp && ./main
Run Code Online (Sandbox Code Playgroud)

它不会编译:

main.cpp: In function ‘int main()’:
main.cpp:12:26: error: cannot use typeid with -fno-rtti
     std::cout << typeid(X) << std::endl;
                          ^
Run Code Online (Sandbox Code Playgroud)

这是否意味着type_info是RTTI的一部分,还是仅仅是GCC 的行为

c++ gcc rtti

7
推荐指数
1
解决办法
1888
查看次数

如何最好地在DWScript中公开类实例

我正在使用优秀的Pascal DWScript整合内置脚本功能.我还使用以下命令将自己的Delphi端类定义(TDemo)添加到DWScript:

dwsUnit.ExposeRTTI( TDemo.ClassInfo  )
Run Code Online (Sandbox Code Playgroud)

这只是工作,是快速添加属性和方法的好方法.

我也希望以类似的方式添加现有实例,因此我创建了类型为TDemo的实例FDemo,然后执行:

   dwsUnit.ExposeInstanceToUnit( 'Demo', 'TDemo', FDemo );
Run Code Online (Sandbox Code Playgroud)

这看起来很有前途,但是我从未初始化的单位表中得到一个AV.我也查看了SVN源的单元测试代码,看看这个功能的使用但无济于事.任何人都可以指出我应该添加/更改的内容吗?

delphi rtti dwscript

6
推荐指数
1
解决办法
816
查看次数

如何获取TRTTIParamter的默认值

我有这门课:

TMyClass = class
public
  function DoSomethingNice(const Value: string = 'Yes please!'): Boolean;
end;
Run Code Online (Sandbox Code Playgroud)

现在,使用RTTI,是否可以获取方法DoSomethingNice的参数的默认值?如果是这样,怎么样?

我最感兴趣的是D2010解决方案,但XE也会这样做.

delphi rtti delphi-2010 delphi-xe

6
推荐指数
1
解决办法
476
查看次数

如何在运行时设计器中隐藏继承的已发布属性?

我正在使用属性检查器(例如JVCL库中的漂亮的JvInspector),它很好地让我查看和编辑我的类'TMyClass'的已发布属性.TMyClass来自TFrame并且有一些已发布的属性是我需要查看和编辑的唯一属性.当然TFrame有很多VCL属性,都是已发布的,我也看到了.

如何抑制祖先属性RTTI并留下我自己发布的属性?我正在使用XE3所以世界是我的牡蛎......也许吧.

delphi properties rtti delphi-xe3

6
推荐指数
1
解决办法
2473
查看次数

实现接口在运行时有什么好处?

我正在尝试了解TVirtualInterface类.

{$APPTYPE CONSOLE}

uses
  SysUtils, Rtti;

type
  ISpecificInterface = interface(IInvokable)
    ['{281D8B97-397E-430A-895A-9CA4E1F5FB5F}']
    procedure SpecificProcedure;
  end;

procedure AProcedure(Method: TRttiMethod; const Args: TArray<TValue>;
  out Result: TValue);
begin
  Writeln(Method.ToString);
end;

var
  ISpecificInterfaceInstance: ISpecificInterface;

begin
  ISpecificInterfaceInstance := TVirtualInterface.Create
    (TypeInfo(ISpecificInterface), AProcedure) as ISpecificInterface;

  ISpecificInterfaceInstance.SpecificProcedure;

end. // TVirtualInterface ref. counter is decremented
Run Code Online (Sandbox Code Playgroud)

在运行时实现接口有什么好处?

空间的用途是什么?

delphi oop rtti

6
推荐指数
1
解决办法
209
查看次数