标签: rtti

如何使用RTTI在Delphi中获取访问字段?

考虑以下:

TFieldType = class
  fValue: string;
end;

TMainClass = class
private
  Ffield: TFieldType;
public
  function GetValue: string;
end;
Run Code Online (Sandbox Code Playgroud)

在TMainClass.GetValue中,我试着获取TMainClass字段的值:

function TMainClass.GetValue;
begin
  vCtx := TRTTIContext.Create;
  vType := vCtx.GetType(Self.ClassInfo);
  for vField in vType.GetFields do
    vField.GetValue(
        //Here's the trouble, because i don't know how to get the instance
    );
Run Code Online (Sandbox Code Playgroud)

可能有另一种获取字段值的方法,这些字段是另一个类的实例?

delphi field rtti delphi-2010

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

在运行时获取delphi记录中字段的偏移量

给定记录类型:

TItem = record
   UPC : string[20];
   Price : Currency;
   Cost : Currency;
   ...
end; 
Run Code Online (Sandbox Code Playgroud)

并且字段的名称为字符串,如何在记录中获取该字段的偏移量?我需要在运行时执行此操作 - 要在运行时决定要访问的字段的名称.

例:

var
   pc : Integer;
   fieldName : string;
   value : Currency;
begin
   pc := Integer(@item);                    // item is defined and filled elsewhere
   fieldName := Text1.Text;                 // user might type 'Cost' or 'Price' etc
   Inc(pc, GetItemFieldOffset(fieldName));  // how do I implement GetItemFieldOffset?
   value := PCurrency(pc)^;
   ..
Run Code Online (Sandbox Code Playgroud)

我正在使用Delphi 7.

delphi struct pointers rtti delphi-7

6
推荐指数
2
解决办法
2824
查看次数

在Mac OS X上的-fno-rtti共享库中多态捕获异常

我正在建立一个共享库f-no-rtti.在内部,此库会抛出std:invalid_argument并捕获std::exception,但从catch不输入该子句.

以下代码重现了该问题(g ++ 4.2,Mac OS X 10.6):

// library.cpp: exports f(), compiled with -fno-rtti
#include <stdexcept>
#include <iostream>
extern "C" {
    void f() {
        try {
            throw std::invalid_argument("std::exception handler");
        } catch( std::exception& e) {
            std::cout << e.what() << "\n";
        } catch(...) {
            std::cout << "... handler\n";
        }
    }
}
Run Code Online (Sandbox Code Playgroud)
// main.cpp: the main executable, dynamically loads the library
#include <dlfcn.h>
typedef void(*fPtr)();

int main() {
    void* handle = dlopen( "./libexception_problem.dylib", RTLD_LAZY ); …
Run Code Online (Sandbox Code Playgroud)

c++ macos gcc shared-libraries rtti

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

没有RTTI的C++双重调度"可扩展"

没有人知道的方式在C正确处理双调度++ 而不使用RTTI和dynamic_cast的<>,并且也是溶液,其中,所述类层次是可扩展的,即基类可以从进一步得到,它的定义/实施不需要知道的吗?
我怀疑没有办法,但我很高兴被证明是错的:)

c++ polymorphism overloading double-dispatch rtti

6
推荐指数
2
解决办法
2828
查看次数

TRttiMethod.Invoke函数在重载方法中不起作用?

我正在使用TRttiMethod.Invoke函数创建类的实例,但是当构造函数或方法重载时,rtti不会调用正确的方法.

我写了一个示例应用来说明我的问题.

program ProjectFoo;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  Rtti,
  System.SysUtils;

type
  TFoo=class
  public
    constructor Create(Value :  Integer);overload;
    constructor Create(const Value :  string);overload;
    function Bar(value : integer) : Integer; overload;
    function Bar(const value : string) : string; overload;
  end;

{ TFoo }

constructor TFoo.Create(Value: Integer);
begin
   Writeln(Value);
end;

function TFoo.Bar(value: integer): Integer;
begin
   Writeln(Value);
   Result:=value;
end;

function TFoo.Bar(const value: string): string;
begin
   Writeln(Value);
   Result:=value;
end;


constructor TFoo.Create(const Value: string);
begin
   Writeln(Value);
end;

var
 c : TRttiContext;
 t : …
Run Code Online (Sandbox Code Playgroud)

delphi rtti delphi-xe2

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

Delphi Class Helper RTTI GetMethod

让我们说我有一个示例类助手

TSampleClassHelper = class helper for TSampleClass
public
  procedure SomeHelper;
end;
Run Code Online (Sandbox Code Playgroud)

我做以下事情:

var
  obj :TSampleClass;
begin
  obj:=TSampleClass.Create;
  obj.SomeHelper;
end;
Run Code Online (Sandbox Code Playgroud)

这按预期工作.

但是,如何使用RTTI来调用辅助方法呢?以下似乎不起作用,GetMethod返回nil.

var
  obj :TSampleClass;
  ctx :TRTTIContext;
  rtype :TRTTIType;
  rmethod :TRTTIMethod;
begin
  obj:=TSampleClass.Create;
  rtype:=ctx.GetType(obj.ClassType);
  rmethod:=rtype.GetMethod('SomeHelper'); // rmethod is nil !
end;
Run Code Online (Sandbox Code Playgroud)

那么RTTI不适用于类助手中定义的方法吗?有没有办法解决?

谢谢.

delphi rtti class-helpers

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

对于静态数组,使用RTTI获取记录字段类型失败

我正在尝试获取记录字段的类型以创建正确的比较器(作为任何/几乎任何记录类型的通用解决方案).我找不到静态数组的类型信息:

  TArrFieldTest = record
    a: string;
    b: array[0..3] of byte;
  end;

procedure Test;
var
  rttiContext: TRttiContext;
  rttiType: TRttiType;
  rttiFields: TArray<TRttiField>;
begin
  rttiType := rttiContext.GetType(TypeInfo(TArrFieldTest));
  rttiFields := rttiType.GetFields;
  Assert(rttiFields[0].FieldType<>nil); // it's ok
  Assert(rttiFields[1].FieldType<>nil); // fail here!
end;
Run Code Online (Sandbox Code Playgroud)

对于任何类型的静态数组,FieldType都是nil.任何想法在这里有什么不对?或者也许有更简单的方法来创建与TArray/TDictionary等一起使用的记录的比较器?

delphi rtti delphi-10-seattle

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

FreePascal RTTI.有没有办法调用方法?

我试图找出是否有办法做类似于Delphi的增强型RTTI功能.

据我所知,FPC不提供自Delphi 2010以来Delphi中出现的RTTI功能.但我想找到一些方法在运行时做一些技巧.

typinfo在FPC中使用单位我可以做以下事情:

  • 获取对象发布的属性列表 - getPropList来自typinfo单元;
  • 获取/设置Object的已发布属性的值 - 通过GetPropValue(...): Variant/ SetPropValue(...Value: Variant);
  • 获得发表的方法 - 通过MethodAddres;

但我还没有办法做一些事情,比如:

  • 呼叫方法;
  • 调用构造函数,或创建对象;

更新:构造函数的问题很像方法一 - 我希望有一种方法可以传递不同的参数:

// concept of code
type

TClass = class of TObject;

TMyClass1 = class
  public
    constructor Create(Param1: Integer; Param2: string); override;
  end;

TMyClass2 = class
  public
    constructor Create(ObjectParam: Object); override;
  end;

TParams = array of Variant;

var 
Classes: array of TClass 
Instances: array of Object;
ParamArray: array of TParams; …
Run Code Online (Sandbox Code Playgroud)

delphi runtime rtti fpc

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

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

我正在尝试了解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
查看次数

使用RTTI获取变量名称

我试图像这样使用RTTI获取变量名.

这是我的测试.

type
  TStringHelper = record helper for string
    function Name: string;
  end;

  TMyRecord = record
    Field1:string;
  end;

implementation

{ TStringHelper }
function TStringHelper.Name: string;
var
 context : TRttiContext;
begin
 context := TRttiContext.Create;
 result := context.GetType(@Self).Name; // return empty
 context.Free;
end;

procedure TForm2.FormCreate(Sender: TObject);
var
 r : TMyRecord;
begin
  ShowMessage(r.Field1.Name);
end;
Run Code Online (Sandbox Code Playgroud)

TRttiType返回的名称为空.

有没有办法得到变量名?

delphi rtti

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