考虑以下:
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)
可能有另一种获取字段值的方法,这些字段是另一个类的实例?
给定记录类型:
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.
我正在建立一个共享库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正确处理双调度++ 而不使用RTTI和dynamic_cast的<>,并且也是溶液,其中,所述类层次是可扩展的,即基类可以从进一步得到,它的定义/实施不需要知道的吗?
我怀疑没有办法,但我很高兴被证明是错的:)
我正在使用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) 让我们说我有一个示例类助手
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不适用于类助手中定义的方法吗?有没有办法解决?
谢谢.
我正在尝试获取记录字段的类型以创建正确的比较器(作为任何/几乎任何记录类型的通用解决方案).我找不到静态数组的类型信息:
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功能.
据我所知,FPC不提供自Delphi 2010以来Delphi中出现的RTTI功能.但我想找到一些方法在运行时做一些技巧.
typinfo在FPC中使用单位我可以做以下事情:
getPropList来自typinfo单元;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) 我正在尝试了解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)
在运行时实现接口有什么好处?
空间的用途是什么?
我试图像这样使用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返回的名称为空.
有没有办法得到变量名?
rtti ×10
delphi ×8
c++ ×2
delphi-2010 ×1
delphi-7 ×1
delphi-xe2 ×1
field ×1
fpc ×1
gcc ×1
macos ×1
oop ×1
overloading ×1
pointers ×1
polymorphism ×1
runtime ×1
struct ×1