Jump to content

Search the Community

Showing results for tags 'rtti'.

More search options

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


  • Delphi Questions and Answers
    • Algorithms, Data Structures and Class Design
    • VCL
    • FMX
    • RTL and Delphi Object Pascal
    • Databases
    • Network, Cloud and Web
    • Windows API
    • Cross-platform
    • Delphi IDE and APIs
    • General Help
    • Delphi Third-Party
  • C++Builder Questions and Answers
    • General Help
  • General Discussions
    • Embarcadero Lounge
    • Tips / Blogs / Tutorials / Videos
    • Job Opportunities / Coder for Hire
    • I made this
  • Software Development
    • Project Planning and -Management
    • Software Testing and Quality Assurance
  • Community
    • Community Management

Find results in...

Find results that contain...

Date Created

  • Start


Last Updated

  • Start


Filter by number of...


  • Start




Found 6 results

  1. Hello everyone, I hope this message finds you all in good health! This year and really weird.... But anyway, let's get back to the point. I recently found a little nugget on the Internet developed by the brilliant @Uwe Raabe : it's a Dataset helper that automatically fills in the properties (or even fields) of an object. The source code can be found at this address : https://www.uweraabe.de/Blog/2017/02/09/dataset-enumerator-reloaded/ I have slightly adapted the source code to use TMS Aurelius attributes (using "Column" attribute instead of "DBField" one provided bu Uwe). The Dataset helper works perfectly well "simple" classes such TCustomer = class private [Column('CustNo')] FCustNo: Double; FCompany: string; FAddress1: string; public [DBField('Addr1')] property Address1: string read FAddress1 write FAddress1; property Company: string read FCompany write FCompany; end; But it gets more difficult as soon as my fields are declared this way: TCustomer = class private [Column('CustNo')] FCustNo: Nullable<Double>;; FCompany: Nullable<String>;; FAddress1: string; FEntity: TObject; public [DBField('Addr1')] property Address1: string read FAddress1 write FAddress1; property Company: string read FCompany write FCompany; property Entity: TObject read FEntity write FEntity; end; At runtime application is throwing "Invalid Type Typecast" exception on every TRTTI.GetValue or TRRTI.SetValue procedure TDataSetHelper.TDataSetRecord<T>.TFieldMapping.LoadFromField(var Target: T); begin FRTTIField.SetValue(GetPointer(Target), TValue.FromVariant(FField.Value)); end; procedure TDataSetHelper.TDataSetRecord<T>.TFieldMapping.StoreToField(var Source: T); begin FField.Value := FRTTIField.GetValue(GetPointer(Source)).AsVariant; end; procedure TDataSetHelper.TDataSetRecord<T>.TPropMapping.StoreToField(var Source: T); begin FField.Value := FRTTIProp.GetValue(GetPointer(Source)).AsVariant; end; procedure TDataSetHelper.TDataSetRecord<T>.TPropMapping.LoadFromField(var Target: T); begin FRTTIProp.SetValue(GetPointer(Target), TValue.FromVariant(FField.Value)); end; I guess this is happening because of either reading/writing values from a Record or an Object. I searched (maybe not enough nor thoroughly) the Internet but I wasn't able to solve this by myself. Can someone helps me sorting this out adapting attached unit to handle simple properties types (integer, double, date, string, boolean....) values as well Nullable one ! (and rejects complex types too 🙂 ) I'll really appreciate some help. Kind regards, Stéphane Ps: I have attached modified Uwe's unit file. Ps2: I'm working with Delphi Sydney Aurelius.Dataset.helper.pas
  2. I was looking at an old blog post by Barry Kelly. In particular the function: function TLocation.FieldRef(const name: string): TLocation; var f: TRttiField; begin if FType is TRttiRecordType then begin f := FType.GetField(name); Result.FLocation := PByte(FLocation) + f.Offset; Result.FType := f.FieldType; end else if FType is TRttiInstanceType then begin f := FType.GetField(name); Result.FLocation := PPByte(FLocation)^ + f.Offset; Result.FType := f.FieldType; end else raise Exception.CreateFmt('Field reference applied to type %s, which is not a record or class', [FType.Name]); end; I am puzzled by the line: Result.FLocation := PPByte(FLocation)^ + f.Offset; If Flocation is an object (FType is TRttiInstance type) and I am having a record field inside the object, the Result.FLocation should be PByte(FLocation) + f.offset, i.e. the same as for FType is TRttiRecord. Barry Kelly is probably the guy that wrote the Rtti stuff, so he knows what he is talking about. What I am missing?
  3. I want to get a list of interfaces registered in a Delphi 2007 application (with code from within that application) in order to check for possible duplicate GUIDs. There is a solution on GitHub which uses the System.RTTI unit, but unfortunately that unit is not available in Delphi 2007. Is it possible to do without? I also asked on StackOverflow: https://stackoverflow.com/q/54710667/49925
  4. I can do it without RTTI, but get a compiler error when using RTTI: procedure TForm1.Button1Click(Sender: TObject); var ctx: TRttiContext; rt: TRttiType; fld: TRttiField; proc: TWndMethod; begin proc := TabSet1.WindowProc; // Compiles and works OK without RTTI ctx := TRttiContext.Create; try rt := ctx.GetType(TControl); fld := rt.GetField('FWindowProc'); ShowMessage(fld.GetValue(TabSet1).TypeInfo.Name); // 'TWndMethod' if fld.GetValue(TabSet1).IsType<TWndMethod> then // True proc := fld.GetValue(TabSet1).AsType<TWndMethod>; // E2010 Incompatible types: 'procedure, untyped pointer or untyped parameter' and 'TWndMethod' finally ctx.Free; end; end; Any suggestions?
  5. As you know, modern Delphi versions add the RTTI information to the executable file. RTTI gives you the opportunity to do incredible things in your application. But it is not always necessary. You can disable RTTI in your application by adding the following lines to each unit: {$WEAKLINKRTTI ON} {$RTTI EXPLICIT METHODS([]) PROPERTIES([]) FIELDS([])} But to completely disable RTTI, you need to add these lines to used RTL units too, and rebuild the project. How much will the size of the executable file decrease? Well, I checked it on small utilities from the Delphi Localizer project, and here is the result: kdlscan.exe was 742400 bytes, now 360448 bytes, -51% lngupdate.exe was 727040 bytes, now 282112 bytes, -61% (!!!) The smaller size of an executable file means that the file is read twice as fast from disk. In addition, the processor is more likely to be able to fully fit your utility into its cache. You can give other reasons why this makes sense.
  6. I want to recursively walk the properties of MyVar: TMyOuterType - but the Items list may be empty. How can I walk the base element type of Items, i.e. TMyType - when I have no instance data? type TMyType = class public property One: string; property Two: string; end; TMyType2 = class(TMyType) public property Two: string; end; TMyType3 = class(TMyType2) public property Three: string; end; TMyTypeArray = TArray<TMyType>; // i.e. polymorphic TMyOuterType = class public property Items: TMyTypeArray; end; var MyVar: TMyOuterType;