标签: rtti

Delphi中对象的RTTI

我试图在Delphi中将对象解析为XML,所以我读到了调用对象的ClassInfo方法以获取其RTTI信息.

问题是,这显然只适用于TPersistent对象.否则,我必须在编译器的源代码中专门添加编译器指令{$ M +}以生成RTTI信息.

所以我很高兴地添加了该指令,只是为了发现它,即使它确实从ClassInfo调用返回了一些东西(它曾经返回nil),现在我无法从中检索类的属性,字段或方法.这就像它创建了对象为空.

知道我在这里缺少什么吗?谢谢!

delphi rtti

2
推荐指数
1
解决办法
2653
查看次数

C++ RTTI和派生类

我的C++有点生疏.这是我正在尝试做的事情:

class Cmd { };
class CmdA : public Cmd { };
class CmdB : public Cmd { };
...
Cmd *a = new CmdA ();
Cmd *b = new CmdB ();
Run Code Online (Sandbox Code Playgroud)

第一个问题:

cout << typeid (a).name ()
cout << typeid (b).name ()
Run Code Online (Sandbox Code Playgroud)

两者都返回Cmd*类型.我想要的结果是CmdA*和CmdB*.除此之外的任何方式实现此目的:

if (dynamic_cast <CmdA *> (a)) ...
Run Code Online (Sandbox Code Playgroud)

其次,我想做这样的事情:

class Target {
    public:
        void handleCommand (Cmd *c) { cout << "generic command..." }
        void handleCommand (CmdA *a) { cout << "Cmd A"; }
        void handleCommand (CmdB *b) { …
Run Code Online (Sandbox Code Playgroud)

c++ inheritance rtti

2
推荐指数
1
解决办法
2018
查看次数

如何免费嵌套(对象类型)字段类?

TBaseClass = class
public
  destructor Destroy; override;
end;

TFirstClass = class(TBaseClass)
  FMyProp: string;
end;

TSecondClass = class(TBaseClass)
  FMyFirstClass: TFirstClass;
end;
Run Code Online (Sandbox Code Playgroud)

我需要实现一个DESTRUCTOR,它能够从同一个基类中找到所有(对象类型)字段并给它一个Free来避免所有这些内存泄漏.

为什么?因为FMyFirstClass可以创建或不创建,这取决于我的应用程序的流程,我无法保证何时将其创建为Free it,既不想用NIL检查所有析构函数来检查代码,因为我有一个很多像这样的领域.

我正在尝试使用新的RTTI来获取基于TBaseClass的所有字段,但我无法获得对象字段的实例,而且我没有想法.

我会走正路吗?你建议做什么?

delphi oop rtti

2
推荐指数
1
解决办法
943
查看次数

固定枚举不返回RTTI属性:它是一个错误吗?

我需要浏览一些类的所有已发布属性.未列出类型为具有固定值的枚举的属性.

见下面的例子:

TMyEnum = (meBlue, meRed, meGreen);
TMyEnumWithVals = (mevBlue=1, mevRed=2, mevGreen=3);
TMyClass =
...
published
  property Color: TMyEnum read FColor write SetColor; // This one is found
  property ColorVal: TMyEnumWithVals read FColorVal write SetColorVal; // This one is never found
end;
Run Code Online (Sandbox Code Playgroud)

我需要固定值,因为这些属性存储在数据库中,我需要确保分配的值始终是相同的,无论下一版本中的Delphi编译器选择如何,并防止在枚举列表中任何错误的未来值插入.

我尝试使用新的Delphi 2010 RTTI(带.GetDeclaredProperties)和"旧"RTTI(带GetPropInfos):除上述类型的属性外,找到所有属性.

在所有类中都可以看到相同的行为.我还在一个示例项目中复制了这个.

尝试使用和不使用各种RTTI指令而不进行更改.

这是一个错误,一个已知的限制?是否有解决方法(除了删除枚举的固定值)?

使用Delphi2010 Ent + Update5

[编辑]答案下面提供变通方法:枚举的第一个值必须被设置为0而不是1,和值是连续的.经过测试和工作的解决方案

谢谢,

delphi rtti

2
推荐指数
1
解决办法
995
查看次数

使用Rtti设置方法字段

我正在使用Delphi XE编写基类,这将允许降序类通过应用注释来映射dll方法.但是我得到了一个类型转换错误,这是可以理解的.

本质上,基类应如下所示:

TWrapperBase = class
public
  FLibHandle: THandle;
  procedure MapMethods;
end;

procedure TWrapperBase.MapMethods;
var
  MyField: TRttiField;
  MyAttribute: TCustomAttribute;
  pMethod: pointer;
begin
  FLibHandle := LoadLibrary(PWideChar(aMCLMCR_dll));
  for MyField in TRttiContext.Create.GetType(ClassType).GetFields do
    for MyAttribute in MyField.GetAttributes do
      if MyAttribute.InheritsFrom(TMyMapperAttribute) then
      begin
        pMethod := GetProcAddress(FLibHandle, (MyAttribute as TMyMapperAttribute).TargetMethod);
        if Assigned(pMethod) then
          MyField.SetValue(Self, pMethod); // I get a Typecast error here
end;
Run Code Online (Sandbox Code Playgroud)

降序类看起来像这样:

TDecendant = class(TWrapperBase)
private type
  TSomeDLLMethod = procedure(aParam: TSomeType); cdecl;
private
  [TMyMapperAttribute('MyDllMethodName')]
  FSomeDLLMethod: TSomeDLLMethod;
public
  property SomeDLLMethod: TSomeDLLMethod read FSomeDLLMethod;
end; …
Run Code Online (Sandbox Code Playgroud)

delphi annotations rtti delphi-xe

2
推荐指数
1
解决办法
535
查看次数

dynamic_cast用于多个派生类

我有一个基类和n派生类.我想实例化一个派生类并将其发送到一个接收基类作为参数的函数.在函数内部,我通过使用dynamic_cast找到了哪种类型的派生类,但我不想使用几个if-else语句.相反,我想知道是否有办法找出哪个派生类是为了投出它.这里我以我的代码为例.

class animal{
   public: 
          virtual ~animal() {}
          int eyes;

  };

class dog: public animal{
   public:
         int legs;
         int tail;
  };

class fish: public animal{
   public:
         int mostage;
  };

void functionTest(animal* a){
  if(dynamic_cast<fish*>(a) != NULL){
                             do_something();
                             }
  else if(dynamic_cast<dog*>(a) != NULL){
                              do_something();
                              }
 };
Run Code Online (Sandbox Code Playgroud)

我想对此有一个更一般的方法.像dynamic_cast(a)这样的东西.谢谢!

c++ rtti c++11

2
推荐指数
1
解决办法
428
查看次数

Delphi - 将TValue传递给泛型方法

我需要使用RTTI遍历具有复杂结构的类.该类有几个记录成员,我也想迭代.

 TRTTIHelpers<T> = class
  public
    class function DoGetValuesForClass(aClassInst: T): TStringList;
    class function DoGetValuesForRecord(aRec: T): TStringList;
  end;
Run Code Online (Sandbox Code Playgroud)

我知道当我在课堂上有一个成员时,这是一个记录:

   for prop in rt.GetProperties() do
    begin
      if prop.PropertyType is TRttiRecordType then
      begin
        lValue := prop.GetValue(aInst);
        Result.AddStrings(TRTTIHelpers<T>.DoGetValuesForRecord(TValue)); <--
      end
Run Code Online (Sandbox Code Playgroud)

如何将TValue作为参数传递给DoGetValuesForRecord,以便我也可以遍历记录?

delphi rtti delphi-10.1-berlin

2
推荐指数
1
解决办法
519
查看次数

通过RTTI将TDateTime值传递给OleVariant属性

当我分配一个TDateTime值,以OleVariant使用RTTI的对象的属性,对象变为浮点值.

对象的设计使得此属性可以变为Null或任何数据类型的值.如果它变为浮点数,则应将结果计算为浮点数的差值.如果变为TDateTime,则应将结果计算为两个TDateTime值的差值.

我是否已将值直接传递给它,它会正常工作,但中间有RTTI.

我知道TDateTime内部重新设置为float,但有可能接收到我发送的数据类型吗?

请看tkVariant以下代码示例中的案例:

class procedure TRTTI.SetObjPropValue(obj: TObject; rprop: TRttiProperty; value: OleVariant);
var
  rtyp: TRttiType;
  vt: TVarType;
begin
  if obj = nil then Exit();
  if (rprop <> nil) and (rprop.IsWritable) then begin
    case rprop.PropertyType.TypeKind of
      tkInteger, tkInt64:
        begin
          value := TVarConv.NullableCurr(value);
          if VarIsNumeric(value) then rprop.SetValue(obj, TValue.FromVariant(Trunc(value)));
        end;
      tkFloat:
        begin
          if rprop.PropertyType.Name = 'TDateTime' then
            value := TVarConv.NullableDateTime(value)
          else
            value := TVarConv.NullableFloat(value);
          if not VarIsNull(value) then rprop.SetValue(obj, TValue.FromVariant(value)); …
Run Code Online (Sandbox Code Playgroud)

delphi datetime rtti variant

2
推荐指数
1
解决办法
101
查看次数

使用C ++ RTTI(自省)按字符串查找函数指针?

我想知道是否可以使用RTTI来使用其名称(以字符串形式传递)来获取静态方法/函数指针

到目前为止,我有以下代码:

#include <map>

int Foo() {
  return 42;
}

int Bar() {
  return 117;
}

typedef int (*function_ptr)();

int main() {
  std::map<std::string, function_ptr> fctmap;
  fctmap["Foo"] = Foo;
  fctmap["Bar"] = Bar;
}
Run Code Online (Sandbox Code Playgroud)

就我而言,这种设置和保持函数指针手动映射的方法非常不雅致。有没有一种“自动”方式?

c++ rtti

2
推荐指数
1
解决办法
95
查看次数

c ++ typeid使用get()和*为同一unique_ptr返回不同的值

我遇到了一段代码,typeid用来获取unique_ptr指向多态对象的类型。

class B{virtual void foo()= 0;};
class D:public B{void foo() override{}};

int main()
{
    unique_ptr<B> bd = make_unique<D>();
    if (typeid(*bd) != typeid(bd.get()))
    {
        cout<<"Object types are not same"<<endl;
    }
    cout<<"Type name of *bd.name():      "<<typeid(*bd).name()<<endl;
    cout<<"Type name of bd.get().name(): "<<typeid(bd.get()).name()<<endl;
}
Run Code Online (Sandbox Code Playgroud)

输出为:

Object types are not of same 
Type name of *bd.name():      1D 
Type name of bd.get().name(): P1B
Run Code Online (Sandbox Code Playgroud)

get()的输出与使用*取消引用的输出name()不同。另一个观察结果是,当类中没有定义虚函数时(上述示例中没有),get()和*都打印相同的输出。void foo()

问题:

当类中没有虚函数时,为什么get()和*给出不同的输出?

实时示例:https : //gcc.godbolt.org/z/Tiy-Cn

EDIT-1根据unique_ptr上的*,它说“返回* this拥有的对象,等效于* get()。”

c++ inheritance rtti typeid unique-ptr

2
推荐指数
1
解决办法
59
查看次数