标签: 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
查看次数

获取特定属性的属性值

我有一个发布道具的类,我将其序列化为XML.

MyAttr = class(TCustomAttribute)
private
  FName: string;
public
  constructor Create(const Name: string);
  property Name: string read FName write FName;
end;

MyClass = class(TPersistent)
private
  FClassCaption: string;
published
  [MyAttr('Class')]
  property ClassCaption: string read FClassCaption write FClassCaption;
end;
Run Code Online (Sandbox Code Playgroud)

由于XML大小至关重要,我使用属性为属性提供更短的名称(即我无法定义名为'Class'的属性).序列化通过以下方式实现:

lPropCount := GetPropList(PTypeInfo(Obj.ClassInfo), lPropList);
for i := 0 to lPropCount - 1 do begin
  lPropInfo := lPropList^[i];
  lPropName := string(lPropInfo^.Name);

  if IsPublishedProp(Obj, lPropName) then begin
    ItemNode := RootNode.AddChild(lPropName);
    ItemNode.NodeValue := VarToStr(GetPropValue(Obj, lPropName, False));
  end;
end;
Run Code Online (Sandbox Code Playgroud)

我需要条件:如果属性标记为MyAttr,则获取"MyAttr.Name"而不是"lPropInfo ^ .Name".

delphi attributes rtti

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

如何在没有实例化的情况下确保RTTI可用于某个类?

我最近在这个论坛上发布了一个问题,询问有关DXE2可执行文件中缺少RTTI信息的任何建议.

那篇文章是我实际案例的精简版.RRUZ来救援,因此被剥离的版本很快得到了解决.但是,最初的问题仍然存在,所以我现在正在全力发布."主要":

program MissingRTTI;
{$APPTYPE CONSOLE}
uses
  System.SysUtils, RTTI, MyUnit in 'MyUnit.pas', RTTIUtil in 'RTTIUtil.pas';
var
  RHelp:  TRttiHelper;
begin
  RHelp := TRttiHelper.Create();
  if (RHelp.IsTypeFound('MyUnit.TMyClass')) then WriteLn('TMyClass was found.')
  else WriteLn('TMyClass was not found.');
  ReadLn;
  RHelp.Free();
end.
Run Code Online (Sandbox Code Playgroud)

RTTIUtil.pas:

unit RTTIUtil;
interface
uses
  MyUnit;
type
  TRttiHelper = class(TObject)
  public
    function IsTypeFound(TypeName: string) : boolean;
  end;
implementation
uses
  RTTI;
function TRttiHelper.IsTypeFound(TypeName: string): boolean;
var
  rCtx:   TRttiContext;
  rType:  TRttiType;
begin
  Result := false;
  rCtx := TRttiContext.Create();
  rType := rCtx.FindType(TypeName);
  if (rType …
Run Code Online (Sandbox Code Playgroud)

delphi rtti delphi-xe2

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

我们可以使用RTTI按名称查找函数/过程并运行它们吗?

因为我们可以找到一个Property或者一个Object使用RTTI,我们可以在内存中搜索某个function或者procedure(不是来自一个对象method但是来自一个unit)知道它的名字吗?

如果我们可以,是否可以执行它发送它的参数?

delphi rtti delphi-xe3

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

是否有任何Delphi版本可以发出包含tkUnknown的RTTI?

只是为了确保我没有忽略一个奇怪的边缘情况,因为我发现了一个产生它的情况,但我想确保:

是否有任何Delphi版本可以发出包含类型tkUnknownTTypeKind的 RTTI ?

如果是这样:

  • 任何文件参考?
  • 什么类型会产生它?

在当前的Delphi XE5 RTL,我能找到处理的唯一地方tkUnknownTValue,但我还没有发现在RTL,设置了一个代码路径TValue包含所属类别tkUnknown作为.

delphi rtti

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

如何存储参数化方法的类型参数,然后使用它们将JSON对象转换为泛型类型的普通对象?

我正在尝试为Delphi和.NET编写通用的消息传递系统.系统允许将消息定义为普通对象,并将消息处理程序定义为对这些对象起作用的匿名方法.

对象将转换为JSON,并在同一台计算机上运行的应用程序之间传递.每个应用程序都维护一个理解特定消息类型的处理程序列表.

我的类有许多参数化注册方法.有些采用单一类型参数.有些参数采用一对参数,其中一个表示请求对象,另一个表示响应对象.以下是请求/响应处理程序注册的内容:

procedure TTelegraph.RegisterRequestHandler<TRequest, TResponse>
  (requestTypeToHandle: string; handler: TFunc<TRequest, TResponse>);
begin
  FRequestHandlers.Add(requestTypeToHandle,
    TRequestHandler<TRequest, TResponse>.Create(handler,
    TRequest,
    TResponse));
end;
Run Code Online (Sandbox Code Playgroud)

FRequestHandlers是一个TDictionary<string,TRequestHandler>.注册方法如下调用:

  FTelegraph.RegisterRequestHandler<TTestRequest, TTestResponse>('My Request', 
    function(x: TTestRequest): TTestResponse
    begin
      Result := TTestResponse.Create;
      Result.Number := x.Number;
      Result.Message := Format('Received: %s', [x.Message]);
    end);
Run Code Online (Sandbox Code Playgroud)

泛型TRequestHandler<T1,T2>是一个DTO,它包含处理程序以及类型TRequestTResponse.它继承自非泛型TRequestHandler.我不确定是否有更好的方法可以解决这个问题,但这是我能想到的在单个集合中存储多个不相关类型的唯一方法.

这一切似乎都很好.问题是收到请求消息时.处理请求消息的C#代码如下所示:

private void ProcessRequestTelegram(Telegram request)
{
    var requestType = _RequestHandlers[request.MessageType].RequestType;
    var typedRequest = JsonConvert.DeserializeObject(request.Payload, requestType);
    var result = _RequestHandlers[request.MessageType].Handler.DynamicInvoke(typedRequest);
    var jsonPayload = JsonConvert.SerializeObject(result);
    var response = new Telegram()
    {
        Payload …
Run Code Online (Sandbox Code Playgroud)

delphi generics json rtti delphi-xe7

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

使用RTTI时,我们如何获取和设置更深层次的子属性?

概观

我很感激之前已经提出过几个类似的问题:

但是,我没有进一步了解如何将RTTI用于我的需求.

我也花了很多时间和精力来写这个问题所以我希望它不会被关闭:)

工作实例

我在下面有几个过程可以输出到TStrings列表中的组件的属性名称,值和类型.原始来源不是我的,我只是做了一些小改动,整理了代码并将它们放入一些整洁的可重用程序:


下面将输出属性名称,例如:

  • 颜色
  • DoubleBuffered
  • 启用
  • 高度
  • 宽度
procedure GetComponentPropertyNames(Component: TComponent; OutList: TStrings);
var
  I: Integer;
  Count, Size: Integer;
  PropList: PPropList;
  PropInfo: PPropInfo;
begin
  OutList.BeginUpdate;
  try
    OutList.Clear;

    Count := GetPropList(Component.ClassInfo, tkAny, nil);
    Size  := Count * SizeOf(Pointer);
    GetMem(PropList, Size);
    try
      Count := GetPropList(Component.ClassInfo, tkAny, PropList);
      for I := 0 to Count -1 do
      begin
        PropInfo := PropList^[I];
        if not (PropInfo^.PropType^.Kind = tkMethod) then
        begin
          OutList.Add(PropInfo^.Name);
        end;
      end;
    finally
      FreeMem(PropList);
    end;
  finally
    OutList.EndUpdate; …
Run Code Online (Sandbox Code Playgroud)

delphi rtti delphi-xe7

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

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
查看次数

RTTI:获取字符列的长度

我的功能模块在运行时会收到一个表名和一个列名。

我想获取列的长度:透明表中允许多少个字符?

我使用了我最喜欢的搜索引擎,并发现了RTTS

但是文档中的例子将变量传递给RTTS方法DESCRIBE_BY_DATA; 就我而言,我没有变量,而在table_name和中只有类型名称column_name

如何获得长度?

sap abap rtti

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

如何避免 C++17 中的虚拟继承?

让我们看看示例类。基类是ITransport,传输类接口:

class ITransport {
  public:
    virtual void move(const Path& p) = 0;
    virtual double estimateTime(const Path& path) = 0;
    /*Some more methods.*/
};
Run Code Online (Sandbox Code Playgroud)

执行:

class Transport : public ITransport { 
  public:
    virtual void move(const Path& p) override {
        currPoint_ = p.lastPoint(); 
    }
    /*Some more methods.*/
  private:
    Point currPoint_;
};
Run Code Online (Sandbox Code Playgroud)

我们还假设我们要创建一个自移动的运输类:

template <typename EnergySource>
class SelfMovingTransport : public Transport {
  /*Some special methods for self moving transport.*/
};

Run Code Online (Sandbox Code Playgroud)

自动运输最简单的例子是汽车:

template <typename EnergySource>
class Car : public SelfMovingTransport <EnergySource> { …
Run Code Online (Sandbox Code Playgroud)

c++ multiple-inheritance rtti c++17

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